From b5b344787ba362d146651967691da117a12ff61d Mon Sep 17 00:00:00 2001 From: Waldemar Brodkorb Date: Sun, 22 Jan 2017 10:08:01 +0100 Subject: nds32: use the kernel source from Andes --- mk/kernel-ver.mk | 6 + target/config/Config.in.kernelversion | 5 + target/linux/patches/3.4.113/nds32.patch | 72144 ----------------------------- 3 files changed, 11 insertions(+), 72144 deletions(-) delete mode 100644 target/linux/patches/3.4.113/nds32.patch diff --git a/mk/kernel-ver.mk b/mk/kernel-ver.mk index 5f8b991a0..44e61a1ba 100644 --- a/mk/kernel-ver.mk +++ b/mk/kernel-ver.mk @@ -69,3 +69,9 @@ KERNEL_RELEASE:= 1 KERNEL_VERSION:= $(KERNEL_FILE_VER)-$(KERNEL_RELEASE) KERNEL_HASH:= d7d0ee4588711d4f85ed67b65d447b4bbbe215e600a771fb87a62524b6341c43 endif +ifeq ($(ADK_TARGET_KERNEL_VERSION_3_4_NDS32),y) +KERNEL_FILE_VER:= 3.4 +KERNEL_RELEASE:= 1 +KERNEL_VERSION:= $(KERNEL_FILE_VER)-$(KERNEL_RELEASE) +KERNEL_HASH:= 1aa3dd419c848d688ecc626db0283981334749502cd0dc3500a63facf285ba2f +endif diff --git a/target/config/Config.in.kernelversion b/target/config/Config.in.kernelversion index 35c8310e5..f3b9c54bc 100644 --- a/target/config/Config.in.kernelversion +++ b/target/config/Config.in.kernelversion @@ -120,6 +120,7 @@ config ADK_TARGET_KERNEL_VERSION_3_4 depends on !ADK_TARGET_ARCH_ARC depends on !ADK_TARGET_ARCH_BFIN depends on !ADK_TARGET_ARCH_H8300 + depends on !ADK_TARGET_ARCH_NDS32 depends on !ADK_TARGET_ARCH_NIOS2 depends on !ADK_TARGET_ARCH_OR1K depends on !ADK_TARGET_ARCH_SPARC @@ -134,6 +135,10 @@ config ADK_TARGET_KERNEL_VERSION_3_4 depends on !ADK_TARGET_CPU_MIPS_MIPS32R6 depends on !ADK_TARGET_CPU_MIPS64_MIPS64R6 +config ADK_TARGET_KERNEL_VERSION_3_4_NDS32 + bool "3.4-nds32" + depends on ADK_TARGET_ARCH_NDS32 + config ADK_TARGET_KERNEL_VERSION_3_2 bool "3.2.83" depends on !ADK_TARGET_ARCH_ARC diff --git a/target/linux/patches/3.4.113/nds32.patch b/target/linux/patches/3.4.113/nds32.patch deleted file mode 100644 index b71178b57..000000000 --- a/target/linux/patches/3.4.113/nds32.patch +++ /dev/null @@ -1,72144 +0,0 @@ -diff -Nur linux-3.4.113.orig/arch/nds32/boot/install.sh linux-3.4.113/arch/nds32/boot/install.sh ---- linux-3.4.113.orig/arch/nds32/boot/install.sh 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/boot/install.sh 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,47 @@ -+#!/bin/sh -+# -+# arch/nds32/boot/install.sh -+# -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright (C) 1995 by Linus Torvalds -+# Copyright (C) 2009 Andes Technology Corporation -+# -+# Adapted from code in arch/i386/boot/Makefile by H. Peter Anvin -+# Adapted from code in arch/i386/boot/install.sh by Russell King -+# -+# "make install" script for arm architecture -+# -+# Arguments: -+# $1 - kernel version -+# $2 - kernel image file -+# $3 - kernel map file -+# $4 - default install path (blank if root directory) -+# -+ -+# User may have a custom install script -+if [ -x ~/bin/installkernel ]; then exec ~/bin/installkernel "$@"; fi -+if [ -x /sbin/installkernel ]; then exec /sbin/installkernel "$@"; fi -+ -+# Normal install -+echo "Installing normal kernel" -+base=vmlinux -+ -+if [ -f $4/$base-$1 ]; then -+ mv $4/$base-$1 $4/$base-$1.old -+fi -+cat $2 > $4/$base-$1 -+ -+# Install system map file -+if [ -f $4/System.map-$1 ]; then -+ mv $4/System.map-$1 $4/System.map-$1.old -+fi -+cp $3 $4/System.map-$1 -+ -+if [ -x /sbin/loadmap ]; then -+ /sbin/loadmap -+else -+ echo "You have to install it yourself" -+fi -diff -Nur linux-3.4.113.orig/arch/nds32/boot/Makefile linux-3.4.113/arch/nds32/boot/Makefile ---- linux-3.4.113.orig/arch/nds32/boot/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/boot/Makefile 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,22 @@ -+# -+# arch/nds32/boot/Makefile -+# -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright (C) 1995-2002 Russell King -+# Copyright (C) 2009 Andes Technology Corporation -+# -+ -+targets := Image -+ -+$(obj)/Image: vmlinux FORCE -+ $(call if_changed,objcopy) -+ @echo ' Kernel: $@ is ready' -+ -+.PHONY: FORCE -+install: $(obj)/Image -+ $(CONFIG_SHELL) $(srctree)/$(src)/install.sh $(KERNELRELEASE) \ -+ $(obj)/Image System.map "$(INSTALL_PATH)" -+ -diff -Nur linux-3.4.113.orig/arch/nds32/common/dmabounce.c linux-3.4.113/arch/nds32/common/dmabounce.c ---- linux-3.4.113.orig/arch/nds32/common/dmabounce.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/common/dmabounce.c 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,672 @@ -+/* -+ * arch/nds32/common/dmabounce.c -+ * -+ * Special dma_{map/unmap/dma_sync}_* routines for systems that have -+ * limited DMA windows. These functions utilize bounce buffers to -+ * copy data to/from buffers located outside the DMA region. This -+ * only works for systems in which DMA memory is at the bottom of -+ * RAM and the remainder of memory is at the top an the DMA memory -+ * can be marked as ZONE_DMA. Anything beyond that such as discontigous -+ * DMA windows will require custom implementations that reserve memory -+ * areas at early bootup. -+ * -+ * Original version by Brad Parker (brad@heeltoe.com) -+ * Re-written by Christopher Hoover -+ * Made generic by Deepak Saxena -+ * -+ * Copyright (C) 2002 Hewlett Packard Company. -+ * Copyright (C) 2004 MontaVista Software, Inc. -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#undef DEBUG -+ -+#undef STATS -+#ifdef STATS -+#define DO_STATS(X) do { X ; } while (0) -+#else -+#define DO_STATS(X) do { } while (0) -+#endif -+ -+/* ************************************************** */ -+ -+struct safe_buffer { -+ struct list_head node; -+ -+ /* original request */ -+ void *ptr; -+ size_t size; -+ int direction; -+ -+ /* safe buffer info */ -+ struct dma_pool *pool; -+ void *safe; -+ dma_addr_t safe_dma_addr; -+}; -+ -+struct dmabounce_device_info { -+ struct list_head node; -+ -+ struct device *dev; -+ struct dma_pool *small_buffer_pool; -+ struct dma_pool *large_buffer_pool; -+ struct list_head safe_buffers; -+ unsigned long small_buffer_size, large_buffer_size; -+#ifdef STATS -+ unsigned long sbp_allocs; -+ unsigned long lbp_allocs; -+ unsigned long total_allocs; -+ unsigned long map_op_count; -+ unsigned long bounce_count; -+#endif -+}; -+ -+static LIST_HEAD(dmabounce_devs); -+ -+#ifdef STATS -+static void print_alloc_stats(struct dmabounce_device_info *device_info) -+{ -+ printk(KERN_INFO -+ "%s: dmabounce: sbp: %lu, lbp: %lu, other: %lu, total: %lu\n", -+ device_info->dev->bus_id, -+ device_info->sbp_allocs, device_info->lbp_allocs, -+ device_info->total_allocs - device_info->sbp_allocs - -+ device_info->lbp_allocs, device_info->total_allocs); -+} -+#endif -+ -+/* find the given device in the dmabounce device list */ -+static inline struct dmabounce_device_info *find_dmabounce_dev(struct device -+ *dev) -+{ -+ struct list_head *entry; -+ -+ list_for_each(entry, &dmabounce_devs) { -+ struct dmabounce_device_info *d = -+ list_entry(entry, struct dmabounce_device_info, node); -+ -+ if (d->dev == dev) -+ return d; -+ } -+ return NULL; -+} -+ -+/* allocate a 'safe' buffer and keep track of it */ -+static inline struct safe_buffer *alloc_safe_buffer(struct dmabounce_device_info -+ *device_info, void *ptr, -+ size_t size, -+ enum dma_data_direction dir) -+{ -+ struct safe_buffer *buf; -+ struct dma_pool *pool; -+ struct device *dev = device_info->dev; -+ void *safe; -+ dma_addr_t safe_dma_addr; -+ -+ dev_dbg(dev, "%s(ptr=%p, size=%d, dir=%d)\n", __func__, ptr, size, dir); -+ -+ DO_STATS(device_info->total_allocs++); -+ -+ buf = kmalloc(sizeof(struct safe_buffer), GFP_ATOMIC); -+ if (buf == NULL) { -+ dev_warn(dev, "%s: kmalloc failed\n", __func__); -+ return NULL; -+ } -+ -+ if (size <= device_info->small_buffer_size) { -+ pool = device_info->small_buffer_pool; -+ safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); -+ -+ DO_STATS(device_info->sbp_allocs++); -+ } else if (size <= device_info->large_buffer_size) { -+ pool = device_info->large_buffer_pool; -+ safe = dma_pool_alloc(pool, GFP_ATOMIC, &safe_dma_addr); -+ -+ DO_STATS(device_info->lbp_allocs++); -+ } else { -+ pool = NULL; -+ safe = -+ dma_alloc_coherent(dev, size, &safe_dma_addr, GFP_ATOMIC); -+ } -+ -+ if (safe == NULL) { -+ dev_warn(device_info->dev, -+ "%s: could not alloc dma memory (size=%d)\n", -+ __func__, size); -+ kfree(buf); -+ return NULL; -+ } -+#ifdef STATS -+ if (device_info->total_allocs % 1000 == 0) -+ print_alloc_stats(device_info); -+#endif -+ -+ buf->ptr = ptr; -+ buf->size = size; -+ buf->direction = dir; -+ buf->pool = pool; -+ buf->safe = safe; -+ buf->safe_dma_addr = safe_dma_addr; -+ -+ list_add(&buf->node, &device_info->safe_buffers); -+ -+ return buf; -+} -+ -+/* determine if a buffer is from our "safe" pool */ -+static inline struct safe_buffer *find_safe_buffer(struct dmabounce_device_info -+ *device_info, -+ dma_addr_t safe_dma_addr) -+{ -+ struct list_head *entry; -+ -+ list_for_each(entry, &device_info->safe_buffers) { -+ struct safe_buffer *b = -+ list_entry(entry, struct safe_buffer, node); -+ -+ if (b->safe_dma_addr == safe_dma_addr) -+ return b; -+ } -+ -+ return NULL; -+} -+ -+static inline void -+free_safe_buffer(struct dmabounce_device_info *device_info, -+ struct safe_buffer *buf) -+{ -+ dev_dbg(device_info->dev, "%s(buf=%p)\n", __func__, buf); -+ -+ list_del(&buf->node); -+ -+ if (buf->pool) -+ dma_pool_free(buf->pool, buf->safe, buf->safe_dma_addr); -+ else -+ dma_free_coherent(device_info->dev, buf->size, buf->safe, -+ buf->safe_dma_addr); -+ -+ kfree(buf); -+} -+ -+/* ************************************************** */ -+ -+#ifdef STATS -+ -+static void print_map_stats(struct dmabounce_device_info *device_info) -+{ -+ printk(KERN_INFO -+ "%s: dmabounce: map_op_count=%lu, bounce_count=%lu\n", -+ device_info->dev->bus_id, -+ device_info->map_op_count, device_info->bounce_count); -+} -+#endif -+ -+static inline dma_addr_t -+map_single(struct device *dev, void *ptr, size_t size, -+ enum dma_data_direction dir) -+{ -+ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); -+ dma_addr_t dma_addr; -+ int needs_bounce = 0; -+ -+ if (device_info) -+ DO_STATS(device_info->map_op_count++); -+ -+ dma_addr = virt_to_dma(dev, ptr); -+ -+ if (dev->dma_mask) { -+ unsigned long mask = *dev->dma_mask; -+ unsigned long limit; -+ -+ limit = (mask + 1) & ~mask; -+ if (limit && size > limit) { -+ dev_err(dev, "DMA mapping too big (requested %#x " -+ "mask %#Lx)\n", size, *dev->dma_mask); -+ return ~0; -+ } -+ -+ /* -+ * Figure out if we need to bounce from the DMA mask. -+ */ -+ needs_bounce = (dma_addr | (dma_addr + size - 1)) & ~mask; -+ } -+ -+ if (device_info -+ && (needs_bounce || dma_needs_bounce(dev, dma_addr, size))) { -+ struct safe_buffer *buf; -+ -+ buf = alloc_safe_buffer(device_info, ptr, size, dir); -+ if (buf == 0) { -+ dev_err(dev, "%s: unable to map unsafe buffer %p!\n", -+ __func__, ptr); -+ return 0; -+ } -+ -+ dev_dbg(dev, -+ "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", -+ __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr), -+ buf->safe, (void *)buf->safe_dma_addr); -+ -+ if ((dir == DMA_TO_DEVICE) || (dir == DMA_BIDIRECTIONAL)) { -+ dev_dbg(dev, "%s: copy unsafe %p to safe %p, size %d\n", -+ __func__, ptr, buf->safe, size); -+ memcpy(buf->safe, ptr, size); -+ } -+ consistent_sync(buf->safe, size, dir); -+ -+ dma_addr = buf->safe_dma_addr; -+ } else { -+ consistent_sync(ptr, size, dir); -+ } -+ -+ return dma_addr; -+} -+ -+static inline void -+unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); -+ struct safe_buffer *buf = NULL; -+ -+ /* -+ * Trying to unmap an invalid mapping -+ */ -+ if (dma_addr == ~0) { -+ dev_err(dev, "Trying to unmap invalid mapping\n"); -+ return; -+ } -+ -+ if (device_info) -+ buf = find_safe_buffer(device_info, dma_addr); -+ -+ if (buf) { -+ BUG_ON(buf->size != size); -+ -+ dev_dbg(dev, -+ "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", -+ __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr), -+ buf->safe, (void *)buf->safe_dma_addr); -+ -+ DO_STATS(device_info->bounce_count++); -+ -+ if ((dir == DMA_FROM_DEVICE) || (dir == DMA_BIDIRECTIONAL)) { -+ dev_dbg(dev, -+ "%s: copy back safe %p to unsafe %p size %d\n", -+ __func__, buf->safe, buf->ptr, size); -+ memcpy(buf->ptr, buf->safe, size); -+ } -+ free_safe_buffer(device_info, buf); -+ } -+} -+ -+static inline void -+sync_single(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); -+ struct safe_buffer *buf = NULL; -+ -+ if (device_info) -+ buf = find_safe_buffer(device_info, dma_addr); -+ -+ if (buf) { -+ /* -+ * Both of these checks from original code need to be -+ * commented out b/c some drivers rely on the following: -+ * -+ * 1) Drivers may map a large chunk of memory into DMA space -+ * but only sync a small portion of it. Good example is -+ * allocating a large buffer, mapping it, and then -+ * breaking it up into small descriptors. No point -+ * in syncing the whole buffer if you only have to -+ * touch one descriptor. -+ * -+ * 2) Buffers that are mapped as DMA_BIDIRECTIONAL are -+ * usually only synced in one dir at a time. -+ * -+ * See drivers/net/eepro100.c for examples of both cases. -+ * -+ * -ds -+ * -+ * BUG_ON(buf->size != size); -+ * BUG_ON(buf->direction != dir); -+ */ -+ -+ dev_dbg(dev, -+ "%s: unsafe buffer %p (phy=%p) mapped to %p (phy=%p)\n", -+ __func__, buf->ptr, (void *)virt_to_dma(dev, buf->ptr), -+ buf->safe, (void *)buf->safe_dma_addr); -+ -+ DO_STATS(device_info->bounce_count++); -+ -+ switch (dir) { -+ case DMA_FROM_DEVICE: -+ dev_dbg(dev, -+ "%s: copy back safe %p to unsafe %p size %d\n", -+ __func__, buf->safe, buf->ptr, size); -+ memcpy(buf->ptr, buf->safe, size); -+ break; -+ case DMA_TO_DEVICE: -+ dev_dbg(dev, -+ "%s: copy out unsafe %p to safe %p, size %d\n", -+ __func__, buf->ptr, buf->safe, size); -+ memcpy(buf->safe, buf->ptr, size); -+ break; -+ case DMA_BIDIRECTIONAL: -+ BUG(); /* is this allowed? what does it mean? */ -+ default: -+ BUG(); -+ } -+ consistent_sync(buf->safe, size, dir); -+ } else { -+ consistent_sync(dma_to_virt(dev, dma_addr), size, dir); -+ } -+} -+ -+/* ************************************************** */ -+ -+/* -+ * see if a buffer address is in an 'unsafe' range. if it is -+ * allocate a 'safe' buffer and copy the unsafe buffer into it. -+ * substitute the safe buffer for the unsafe one. -+ * (basically move the buffer from an unsafe area to a safe one) -+ */ -+dma_addr_t -+dma_map_single(struct device *dev, void *ptr, size_t size, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ dma_addr_t dma_addr; -+ -+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", __func__, ptr, size, dir); -+ -+ BUG_ON(dir == DMA_NONE); -+ -+ local_irq_save(flags); -+ -+ dma_addr = map_single(dev, ptr, size, dir); -+ -+ local_irq_restore(flags); -+ -+ return dma_addr; -+} -+ -+/* -+ * see if a mapped address was really a "safe" buffer and if so, copy -+ * the data from the safe buffer back to the unsafe buffer and free up -+ * the safe buffer. (basically return things back to the way they -+ * should be) -+ */ -+ -+void -+dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ -+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", -+ __func__, (void *)dma_addr, size, dir); -+ -+ BUG_ON(dir == DMA_NONE); -+ -+ local_irq_save(flags); -+ -+ unmap_single(dev, dma_addr, size, dir); -+ -+ local_irq_restore(flags); -+} -+ -+int -+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ int i; -+ -+ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); -+ -+ BUG_ON(dir == DMA_NONE); -+ -+ local_irq_save(flags); -+ -+ for (i = 0; i < nents; i++, sg++) { -+ struct page *page = sg->page; -+ unsigned int offset = sg->offset; -+ unsigned int length = sg->length; -+ void *ptr = page_address(page) + offset; -+ -+ sg->dma_address = map_single(dev, ptr, length, dir); -+ } -+ -+ local_irq_restore(flags); -+ -+ return nents; -+} -+ -+void -+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ int i; -+ -+ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); -+ -+ BUG_ON(dir == DMA_NONE); -+ -+ local_irq_save(flags); -+ -+ for (i = 0; i < nents; i++, sg++) { -+ dma_addr_t dma_addr = sg->dma_address; -+ unsigned int length = sg->length; -+ -+ unmap_single(dev, dma_addr, length, dir); -+ } -+ -+ local_irq_restore(flags); -+} -+ -+void -+dma_sync_single_for_cpu(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ -+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", -+ __func__, (void *)dma_addr, size, dir); -+ -+ local_irq_save(flags); -+ -+ sync_single(dev, dma_addr, size, dir); -+ -+ local_irq_restore(flags); -+} -+ -+void -+dma_sync_single_for_device(struct device *dev, dma_addr_t dma_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ -+ dev_dbg(dev, "%s(ptr=%p,size=%d,dir=%x)\n", -+ __func__, (void *)dma_addr, size, dir); -+ -+ local_irq_save(flags); -+ -+ sync_single(dev, dma_addr, size, dir); -+ -+ local_irq_restore(flags); -+} -+ -+void -+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ int i; -+ -+ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); -+ -+ BUG_ON(dir == DMA_NONE); -+ -+ local_irq_save(flags); -+ -+ for (i = 0; i < nents; i++, sg++) { -+ dma_addr_t dma_addr = sg->dma_address; -+ unsigned int length = sg->length; -+ -+ sync_single(dev, dma_addr, length, dir); -+ } -+ -+ local_irq_restore(flags); -+} -+ -+void -+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ unsigned long flags; -+ int i; -+ -+ dev_dbg(dev, "%s(sg=%p,nents=%d,dir=%x)\n", __func__, sg, nents, dir); -+ -+ BUG_ON(dir == DMA_NONE); -+ -+ local_irq_save(flags); -+ -+ for (i = 0; i < nents; i++, sg++) { -+ dma_addr_t dma_addr = sg->dma_address; -+ unsigned int length = sg->length; -+ -+ sync_single(dev, dma_addr, length, dir); -+ } -+ -+ local_irq_restore(flags); -+} -+ -+int -+dmabounce_register_dev(struct device *dev, unsigned long small_buffer_size, -+ unsigned long large_buffer_size) -+{ -+ struct dmabounce_device_info *device_info; -+ -+ device_info = kmalloc(sizeof(struct dmabounce_device_info), GFP_ATOMIC); -+ if (!device_info) { -+ printk(KERN_ERR -+ "Could not allocated dmabounce_device_info for %s", -+ dev->bus_id); -+ return -ENOMEM; -+ } -+ -+ device_info->small_buffer_pool = -+ dma_pool_create("small_dmabounce_pool", -+ dev, small_buffer_size, 0 /* byte alignment */ , -+ 0 /* no page-crossing issues */ ); -+ if (!device_info->small_buffer_pool) { -+ printk(KERN_ERR -+ "dmabounce: could not allocate small DMA pool for %s\n", -+ dev->bus_id); -+ kfree(device_info); -+ return -ENOMEM; -+ } -+ -+ if (large_buffer_size) { -+ device_info->large_buffer_pool = -+ dma_pool_create("large_dmabounce_pool", -+ dev, -+ large_buffer_size, 0 /* byte alignment */ , -+ 0 /* no page-crossing issues */ ); -+ if (!device_info->large_buffer_pool) { -+ printk(KERN_ERR -+ "dmabounce: could not allocate large DMA pool for %s\n", -+ dev->bus_id); -+ dma_pool_destroy(device_info->small_buffer_pool); -+ -+ return -ENOMEM; -+ } -+ } -+ -+ device_info->dev = dev; -+ device_info->small_buffer_size = small_buffer_size; -+ device_info->large_buffer_size = large_buffer_size; -+ INIT_LIST_HEAD(&device_info->safe_buffers); -+ -+#ifdef STATS -+ device_info->sbp_allocs = 0; -+ device_info->lbp_allocs = 0; -+ device_info->total_allocs = 0; -+ device_info->map_op_count = 0; -+ device_info->bounce_count = 0; -+#endif -+ -+ list_add(&device_info->node, &dmabounce_devs); -+ -+ printk(KERN_INFO "dmabounce: registered device %s on %s bus\n", -+ dev->bus_id, dev->bus->name); -+ -+ return 0; -+} -+ -+void dmabounce_unregister_dev(struct device *dev) -+{ -+ struct dmabounce_device_info *device_info = find_dmabounce_dev(dev); -+ -+ if (!device_info) { -+ printk(KERN_WARNING -+ "%s: Never registered with dmabounce but attempting" -+ "to unregister!\n", dev->bus_id); -+ return; -+ } -+ -+ if (!list_empty(&device_info->safe_buffers)) { -+ printk(KERN_ERR -+ "%s: Removing from dmabounce with pending buffers!\n", -+ dev->bus_id); -+ BUG(); -+ } -+ -+ if (device_info->small_buffer_pool) -+ dma_pool_destroy(device_info->small_buffer_pool); -+ if (device_info->large_buffer_pool) -+ dma_pool_destroy(device_info->large_buffer_pool); -+ -+#ifdef STATS -+ print_alloc_stats(device_info); -+ print_map_stats(device_info); -+#endif -+ -+ list_del(&device_info->node); -+ -+ kfree(device_info); -+ -+ printk(KERN_INFO "dmabounce: device %s on %s bus unregistered\n", -+ dev->bus_id, dev->bus->name); -+} -+ -+EXPORT_SYMBOL(dma_map_single); -+EXPORT_SYMBOL(dma_unmap_single); -+EXPORT_SYMBOL(dma_map_sg); -+EXPORT_SYMBOL(dma_unmap_sg); -+EXPORT_SYMBOL(dma_sync_single); -+EXPORT_SYMBOL(dma_sync_sg); -+EXPORT_SYMBOL(dmabounce_register_dev); -+EXPORT_SYMBOL(dmabounce_unregister_dev); -+ -+MODULE_AUTHOR -+ ("Christopher Hoover , Deepak Saxena "); -+MODULE_DESCRIPTION -+ ("Special dma_{map/unmap/dma_sync}_* routines for systems with limited DMA windows"); -+MODULE_LICENSE("GPL"); -diff -Nur linux-3.4.113.orig/arch/nds32/common/Makefile linux-3.4.113/arch/nds32/common/Makefile ---- linux-3.4.113.orig/arch/nds32/common/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/common/Makefile 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,6 @@ -+# -+# Makefile for the linux kernel. -+# -+ -+obj-y += rtctime.o -+obj-$(CONFIG_DMABOUNCE) += dmabounce.o -diff -Nur linux-3.4.113.orig/arch/nds32/common/rtctime.c linux-3.4.113/arch/nds32/common/rtctime.c ---- linux-3.4.113.orig/arch/nds32/common/rtctime.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/common/rtctime.c 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,441 @@ -+/* -+ * linux/arch/nds32/common/rtctime.c -+ * -+ * Copyright (C) 2003 Deep Blue Solutions Ltd. -+ * Based on sa1100-rtc.c, Nils Faerber, CIH, Nicolas Pitre. -+ * Based on rtc.c by Paul Gortmaker -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+static DECLARE_WAIT_QUEUE_HEAD(rtc_wait); -+static struct fasync_struct *rtc_async_queue; -+ -+/* -+ * rtc_lock protects rtc_irq_data -+ */ -+static DEFINE_SPINLOCK(rtc_lock); -+static unsigned long rtc_irq_data; -+ -+/* -+ * rtc_sem protects rtc_inuse and rtc_ops -+ */ -+static DEFINE_MUTEX(rtc_mutex); -+static unsigned long rtc_inuse; -+static struct rtc_ops *rtc_ops; -+ -+#define rtc_epoch 1900UL -+ -+/* -+ * Calculate the next alarm time given the requested alarm time mask -+ * and the current time. -+ */ -+void rtc_next_alarm_time(struct rtc_time *next, struct rtc_time *now, -+ struct rtc_time *alrm) -+{ -+ unsigned long next_time; -+ unsigned long now_time; -+ -+ next->tm_year = now->tm_year; -+ next->tm_mon = now->tm_mon; -+ next->tm_mday = now->tm_mday; -+ next->tm_hour = alrm->tm_hour; -+ next->tm_min = alrm->tm_min; -+ next->tm_sec = alrm->tm_sec; -+ -+ rtc_tm_to_time(now, &now_time); -+ rtc_tm_to_time(next, &next_time); -+ -+ if (next_time < now_time) { -+ /* Advance one day */ -+ next_time += 60 * 60 * 24; -+ rtc_time_to_tm(next_time, next); -+ } -+} -+ -+static inline int rtc_arm_read_time(struct rtc_ops *ops, struct rtc_time *tm) -+{ -+ memset(tm, 0, sizeof(struct rtc_time)); -+ return ops->read_time(tm); -+} -+ -+static inline int rtc_arm_set_time(struct rtc_ops *ops, struct rtc_time *tm) -+{ -+ int ret; -+ -+ ret = rtc_valid_tm(tm); -+ if (ret == 0) -+ ret = ops->set_time(tm); -+ -+ return ret; -+} -+ -+static inline int rtc_arm_read_alarm(struct rtc_ops *ops, -+ struct rtc_wkalrm *alrm) -+{ -+ int ret = -EINVAL; -+ if (ops->read_alarm) { -+ memset(alrm, 0, sizeof(struct rtc_wkalrm)); -+ ret = ops->read_alarm(alrm); -+ } -+ return ret; -+} -+ -+static inline int rtc_arm_set_alarm(struct rtc_ops *ops, -+ struct rtc_wkalrm *alrm) -+{ -+ int ret = -EINVAL; -+ if (ops->set_alarm) -+ ret = ops->set_alarm(alrm); -+ return ret; -+} -+ -+void rtc_update(unsigned long num, unsigned long events) -+{ -+ spin_lock(&rtc_lock); -+ rtc_irq_data = (rtc_irq_data + (num << 8)) | events; -+ spin_unlock(&rtc_lock); -+ -+ wake_up_interruptible(&rtc_wait); -+ kill_fasync(&rtc_async_queue, SIGIO, POLL_IN); -+} -+ -+EXPORT_SYMBOL(rtc_update); -+ -+static ssize_t -+rtc_read(struct file *file, char __user * buf, size_t count, loff_t * ppos) -+{ -+ DECLARE_WAITQUEUE(wait, current); -+ unsigned long data; -+ ssize_t ret; -+ -+ if (count < sizeof(unsigned long)) -+ return -EINVAL; -+ -+ add_wait_queue(&rtc_wait, &wait); -+ do { -+ __set_current_state(TASK_INTERRUPTIBLE); -+ -+ spin_lock_irq(&rtc_lock); -+ data = rtc_irq_data; -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ -+ if (data != 0) { -+ ret = 0; -+ break; -+ } -+ if (file->f_flags & O_NONBLOCK) { -+ ret = -EAGAIN; -+ break; -+ } -+ if (signal_pending(current)) { -+ ret = -ERESTARTSYS; -+ break; -+ } -+ schedule(); -+ } while (1); -+ set_current_state(TASK_RUNNING); -+ remove_wait_queue(&rtc_wait, &wait); -+ -+ if (ret == 0) { -+ ret = put_user(data, (unsigned long __user *)buf); -+ if (ret == 0) -+ ret = sizeof(unsigned long); -+ } -+ return ret; -+} -+ -+static unsigned int rtc_poll(struct file *file, poll_table * wait) -+{ -+ unsigned long data; -+ -+ poll_wait(file, &rtc_wait, wait); -+ -+ spin_lock_irq(&rtc_lock); -+ data = rtc_irq_data; -+ spin_unlock_irq(&rtc_lock); -+ -+ return data != 0 ? POLLIN | POLLRDNORM : 0; -+} -+ -+static int rtc_ioctl(struct inode *inode, struct file *file, unsigned int cmd, -+ unsigned long arg) -+{ -+ struct rtc_ops *ops = file->private_data; -+ struct rtc_time tm; -+ struct rtc_wkalrm alrm; -+ void __user *uarg = (void __user *)arg; -+ int ret = -EINVAL; -+ -+ switch (cmd) { -+ case RTC_ALM_READ: -+ ret = rtc_arm_read_alarm(ops, &alrm); -+ if (ret) -+ break; -+ ret = copy_to_user(uarg, &alrm.time, sizeof(tm)); -+ if (ret) -+ ret = -EFAULT; -+ break; -+ -+ case RTC_ALM_SET: -+ ret = copy_from_user(&alrm.time, uarg, sizeof(tm)); -+ if (ret) { -+ ret = -EFAULT; -+ break; -+ } -+ alrm.enabled = 0; -+ alrm.pending = 0; -+ alrm.time.tm_mday = -1; -+ alrm.time.tm_mon = -1; -+ alrm.time.tm_year = -1; -+ alrm.time.tm_wday = -1; -+ alrm.time.tm_yday = -1; -+ alrm.time.tm_isdst = -1; -+ ret = rtc_arm_set_alarm(ops, &alrm); -+ break; -+ -+ case RTC_RD_TIME: -+ ret = rtc_arm_read_time(ops, &tm); -+ if (ret) -+ break; -+ ret = copy_to_user(uarg, &tm, sizeof(tm)); -+ if (ret) -+ ret = -EFAULT; -+ break; -+ -+ case RTC_SET_TIME: -+ if (!capable(CAP_SYS_TIME)) { -+ ret = -EACCES; -+ break; -+ } -+ ret = copy_from_user(&tm, uarg, sizeof(tm)); -+ if (ret) { -+ ret = -EFAULT; -+ break; -+ } -+ ret = rtc_arm_set_time(ops, &tm); -+ break; -+ -+ case RTC_EPOCH_SET: -+#ifndef rtc_epoch -+ /* -+ * There were no RTC clocks before 1900. -+ */ -+ if (arg < 1900) { -+ ret = -EINVAL; -+ break; -+ } -+ if (!capable(CAP_SYS_TIME)) { -+ ret = -EACCES; -+ break; -+ } -+ rtc_epoch = arg; -+ ret = 0; -+#endif -+ break; -+ -+ case RTC_EPOCH_READ: -+ ret = put_user(rtc_epoch, (unsigned long __user *)uarg); -+ break; -+ -+ case RTC_WKALM_SET: -+ ret = copy_from_user(&alrm, uarg, sizeof(alrm)); -+ if (ret) { -+ ret = -EFAULT; -+ break; -+ } -+ ret = rtc_arm_set_alarm(ops, &alrm); -+ break; -+ -+ case RTC_WKALM_RD: -+ ret = rtc_arm_read_alarm(ops, &alrm); -+ if (ret) -+ break; -+ ret = copy_to_user(uarg, &alrm, sizeof(alrm)); -+ if (ret) -+ ret = -EFAULT; -+ break; -+ -+ default: -+ if (ops->ioctl) -+ ret = ops->ioctl(cmd, arg); -+ break; -+ } -+ return ret; -+} -+ -+static int rtc_open(struct inode *inode, struct file *file) -+{ -+ int ret; -+ -+ mutex_lock(&rtc_mutex); -+ -+ if (rtc_inuse) { -+ ret = -EBUSY; -+ } else if (!rtc_ops || !try_module_get(rtc_ops->owner)) { -+ ret = -ENODEV; -+ } else { -+ file->private_data = rtc_ops; -+ -+ ret = rtc_ops->open ? rtc_ops->open() : 0; -+ if (ret == 0) { -+ spin_lock_irq(&rtc_lock); -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ -+ rtc_inuse = 1; -+ } -+ } -+ mutex_unlock(&rtc_mutex); -+ -+ return ret; -+} -+ -+static int rtc_release(struct inode *inode, struct file *file) -+{ -+ struct rtc_ops *ops = file->private_data; -+ -+ if (ops->release) -+ ops->release(); -+ -+ spin_lock_irq(&rtc_lock); -+ rtc_irq_data = 0; -+ spin_unlock_irq(&rtc_lock); -+ -+ module_put(rtc_ops->owner); -+ rtc_inuse = 0; -+ -+ return 0; -+} -+ -+static int rtc_fasync(int fd, struct file *file, int on) -+{ -+ return fasync_helper(fd, file, on, &rtc_async_queue); -+} -+ -+static struct file_operations rtc_fops = { -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .read = rtc_read, -+ .poll = rtc_poll, -+ .ioctl = rtc_ioctl, -+ .open = rtc_open, -+ .release = rtc_release, -+ .fasync = rtc_fasync, -+}; -+ -+static struct miscdevice rtc_miscdev = { -+ .minor = RTC_MINOR, -+ .name = "rtc", -+ .fops = &rtc_fops, -+}; -+ -+static int rtc_read_proc(char *page, char **start, off_t off, int count, -+ int *eof, void *data) -+{ -+ struct rtc_ops *ops = data; -+ struct rtc_wkalrm alrm; -+ struct rtc_time tm; -+ char *p = page; -+ -+ if (rtc_arm_read_time(ops, &tm) == 0) { -+ p += sprintf(p, -+ "rtc_time\t: %02d:%02d:%02d\n" -+ "rtc_date\t: %04d-%02d-%02d\n" -+ "rtc_epoch\t: %04lu\n", -+ tm.tm_hour, tm.tm_min, tm.tm_sec, -+ tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday, -+ rtc_epoch); -+ } -+ -+ if (rtc_arm_read_alarm(ops, &alrm) == 0) { -+ p += sprintf(p, "alrm_time\t: "); -+ if ((unsigned int)alrm.time.tm_hour <= 24) -+ p += sprintf(p, "%02d:", alrm.time.tm_hour); -+ else -+ p += sprintf(p, "**:"); -+ if ((unsigned int)alrm.time.tm_min <= 59) -+ p += sprintf(p, "%02d:", alrm.time.tm_min); -+ else -+ p += sprintf(p, "**:"); -+ if ((unsigned int)alrm.time.tm_sec <= 59) -+ p += sprintf(p, "%02d\n", alrm.time.tm_sec); -+ else -+ p += sprintf(p, "**\n"); -+ -+ p += sprintf(p, "alrm_date\t: "); -+ if ((unsigned int)alrm.time.tm_year <= 200) -+ p += sprintf(p, "%04d-", alrm.time.tm_year + 1900); -+ else -+ p += sprintf(p, "****-"); -+ if ((unsigned int)alrm.time.tm_mon <= 11) -+ p += sprintf(p, "%02d-", alrm.time.tm_mon + 1); -+ else -+ p += sprintf(p, "**-"); -+ if ((unsigned int)alrm.time.tm_mday <= 31) -+ p += sprintf(p, "%02d\n", alrm.time.tm_mday); -+ else -+ p += sprintf(p, "**\n"); -+ p += sprintf(p, "alrm_wakeup\t: %s\n", -+ alrm.enabled ? "yes" : "no"); -+ p += sprintf(p, "alrm_pending\t: %s\n", -+ alrm.pending ? "yes" : "no"); -+ } -+ -+ if (ops->proc) -+ p += ops->proc(p); -+ -+ return p - page; -+} -+ -+int register_rtc(struct rtc_ops *ops) -+{ -+ int ret = -EBUSY; -+ -+ mutex_lock(&rtc_mutex); -+ if (rtc_ops == NULL) { -+ rtc_ops = ops; -+ -+ ret = misc_register(&rtc_miscdev); -+ if (ret == 0) -+ create_proc_read_entry("driver/rtc", 0, NULL, -+ rtc_read_proc, ops); -+ } -+ mutex_unlock(&rtc_mutex); -+ -+ return ret; -+} -+ -+EXPORT_SYMBOL(register_rtc); -+ -+void unregister_rtc(struct rtc_ops *rtc) -+{ -+ mutex_lock(&rtc_mutex); -+ if (rtc == rtc_ops) { -+ remove_proc_entry("driver/rtc", NULL); -+ misc_deregister(&rtc_miscdev); -+ rtc_ops = NULL; -+ } -+ mutex_unlock(&rtc_mutex); -+} -+ -+EXPORT_SYMBOL(unregister_rtc); -diff -Nur linux-3.4.113.orig/arch/nds32/configs/orca_8k_defconfig linux-3.4.113/arch/nds32/configs/orca_8k_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/orca_8k_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/orca_8k_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,132 @@ -+CONFIG_EXPERIMENTAL=y -+CONFIG_CROSS_COMPILE="nds32le-linux-" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL_SYSCALL=y -+# CONFIG_HOTPLUG is not set -+# CONFIG_SIGNALFD is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_BLK_DEV_BSG is not set -+CONFIG_PLATFORM_AHBDMA=y -+CONFIG_PLATFORM_APBDMA=y -+CONFIG_SYS_CLK=30000000 -+CONFIG_UART_CLK=14745600 -+CONFIG_SDRAM_SIZE=0x40000000 -+CONFIG_CPU_CACHE_NONALIASING=y -+CONFIG_ANDES_PAGE_SIZE_8KB=y -+CONFIG_HIGHMEM=y -+CONFIG_HZ_100=y -+CONFIG_CMDLINE="root=/dev/ram0 rw mem=1024M@0x0 initrd=0x1000000,8M earlyprintk=uart8250-32bit,0x99600000 console=ttyS0,38400n8 loglevel=7 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_IPV6 is not set -+CONFIG_BRIDGE=y -+CONFIG_MTD=y -+CONFIG_MTD_CMDLINE_PARTS=y -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLOCK=y -+CONFIG_MTD_CFI=y -+CONFIG_MTD_CFI_INTELEXT=y -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_PHYSMAP_COMPAT=y -+CONFIG_MTD_PHYSMAP_START=0x80400000 -+CONFIG_MTD_PHYSMAP_LEN=0x2000000 -+CONFIG_MTD_PHYSMAP_BANKWIDTH=4 -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_NETDEVICES=y -+CONFIG_TUN=y -+CONFIG_FTMAC100=y -+# CONFIG_INPUT_MOUSEDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_CPE_TS=y -+# CONFIG_SERIO is not set -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_HW_RANDOM is not set -+CONFIG_GPIOLIB=y -+CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_FTGPIO010=y -+# CONFIG_HWMON is not set -+CONFIG_WATCHDOG=y -+CONFIG_FTWDT010_WATCHDOG=y -+CONFIG_FB=y -+CONFIG_FB_FTLCDC100=y -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+CONFIG_SOUND=y -+CONFIG_SND=y -+CONFIG_SND_PCM_OSS=y -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+CONFIG_SND_FTSSP010=y -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+CONFIG_MMC=y -+CONFIG_MMC_FTSDC010=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_FTRTC010=y -+CONFIG_EXT2_FS=y -+CONFIG_FUSE_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_TMPFS=y -+CONFIG_JFFS2_FS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_V4_1=y -+CONFIG_NFS_USE_LEGACY_DNS=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_FS=y -+CONFIG_DEBUG_SHIRQ=y -+CONFIG_SCHEDSTATS=y -+CONFIG_TIMER_STATS=y -+CONFIG_SLUB_DEBUG_ON=y -+CONFIG_DEBUG_RT_MUTEXES=y -+CONFIG_DEBUG_SPINLOCK=y -+CONFIG_DEBUG_MUTEXES=y -+CONFIG_DEBUG_INFO=y -+CONFIG_DEBUG_MEMORY_INIT=y -+CONFIG_DEBUG_LIST=y -+CONFIG_DEBUG_SG=y -+# CONFIG_FTRACE is not set -+CONFIG_DEBUG_USER=y -+CONFIG_DEBUG_ERRORS=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -diff -Nur linux-3.4.113.orig/arch/nds32/configs/orca_defconfig linux-3.4.113/arch/nds32/configs/orca_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/orca_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/orca_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,125 @@ -+CONFIG_EXPERIMENTAL=y -+CONFIG_CROSS_COMPILE="nds32le-linux-" -+CONFIG_SYSVIPC=y -+CONFIG_POSIX_MQUEUE=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_NAMESPACES=y -+CONFIG_SYSCTL_SYSCALL=y -+CONFIG_KALLSYMS_ALL=y -+# CONFIG_HOTPLUG is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_BLK_DEV_BSG is not set -+CONFIG_MEASURE_INTERRUPT_LATENCY=y -+CONFIG_PLATFORM_AHBDMA=y -+CONFIG_PLATFORM_APBDMA=y -+CONFIG_SYS_CLK=30000000 -+CONFIG_UART_CLK=14745600 -+CONFIG_SDRAM_SIZE=0x40000000 -+CONFIG_MEMORY_START=0x0 -+# CONFIG_HWZOL is not set -+CONFIG_IVIC=y -+CONFIG_HIGH_RES_TIMERS=y -+CONFIG_PREEMPT=y -+CONFIG_HZ_100=y -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_IPV6 is not set -+CONFIG_BRIDGE=y -+CONFIG_MTD=y -+CONFIG_MTD_CMDLINE_PARTS=y -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLOCK=y -+CONFIG_MTD_CFI=y -+CONFIG_MTD_CFI_INTELEXT=y -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_PHYSMAP_COMPAT=y -+CONFIG_MTD_PHYSMAP_START=0x80400000 -+CONFIG_MTD_PHYSMAP_LEN=0x2000000 -+CONFIG_MTD_PHYSMAP_BANKWIDTH=4 -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_NETDEVICES=y -+CONFIG_TUN=y -+CONFIG_FTMAC100=y -+# CONFIG_INPUT_MOUSEDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_CPE_TS=m -+# CONFIG_SERIO is not set -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_HW_RANDOM is not set -+CONFIG_GPIOLIB=y -+CONFIG_GPIO_SYSFS=y -+CONFIG_GPIO_FTGPIO010=m -+# CONFIG_HWMON is not set -+CONFIG_WATCHDOG=y -+CONFIG_FTWDT010_WATCHDOG=m -+CONFIG_FB=y -+CONFIG_FB_FTLCDC100=y -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+CONFIG_SOUND=y -+CONFIG_SND=y -+CONFIG_SND_PCM_OSS=y -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+CONFIG_SND_FTSSP010=m -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+CONFIG_MMC=y -+CONFIG_MMC_FTSDC010=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_RTC_DRV_FTRTC010=y -+CONFIG_EXT2_FS=y -+CONFIG_FUSE_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_TMPFS=y -+CONFIG_TMPFS_POSIX_ACL=y -+CONFIG_CONFIGFS_FS=y -+CONFIG_JFFS2_FS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+CONFIG_NFS_V3_ACL=y -+CONFIG_NFS_V4=y -+CONFIG_NFS_V4_1=y -+CONFIG_NFS_USE_LEGACY_DNS=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_HEADERS_CHECK=y -+CONFIG_DEBUG_SECTION_MISMATCH=y -+# CONFIG_SCHED_DEBUG is not set -+CONFIG_DEBUG_INFO=y -+# CONFIG_FTRACE is not set -+CONFIG_DEBUG_USER=y -+CONFIG_DEBUG_ERRORS=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -diff -Nur linux-3.4.113.orig/arch/nds32/configs/qemu_defconfig linux-3.4.113/arch/nds32/configs/qemu_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/qemu_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/qemu_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,98 @@ -+CONFIG_EXPERIMENTAL=y -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL_SYSCALL=y -+# CONFIG_HOTPLUG is not set -+# CONFIG_SIGNALFD is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_BLK_DEV_BSG is not set -+CONFIG_PLAT_QEMU=y -+CONFIG_SYS_CLK=40000000 -+CONFIG_UART_CLK=14745600 -+CONFIG_SDRAM_SIZE=0x10000000 -+CONFIG_HZ_100=y -+CONFIG_CMDLINE="root=/dev/ram0 rw mem=1024M@0x0 initrd=0x1000000,8M earlyprintk=uart8250-32bit,0x99600000 console=ttyS0,38400n8 loglevel=7 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_IPV6 is not set -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_FTSDC010=y -+CONFIG_NETDEVICES=y -+CONFIG_FTMAC100=y -+# CONFIG_INPUT_MOUSEDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_TOUCHSCREEN=y -+# CONFIG_SERIO is not set -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_HW_RANDOM is not set -+# CONFIG_HWMON is not set -+CONFIG_FB=y -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+CONFIG_EXT2_FS=y -+CONFIG_EXT2_FS_XATTR=y -+CONFIG_EXT2_FS_POSIX_ACL=y -+CONFIG_EXT2_FS_SECURITY=y -+CONFIG_EXT2_FS_XIP=y -+CONFIG_EXT3_FS=y -+CONFIG_EXT3_FS_POSIX_ACL=y -+CONFIG_EXT3_FS_SECURITY=y -+CONFIG_EXT4_FS=y -+CONFIG_EXT4_FS_POSIX_ACL=y -+CONFIG_EXT4_FS_SECURITY=y -+CONFIG_EXT4_DEBUG=y -+CONFIG_FUSE_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_TMPFS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_FS=y -+CONFIG_DEBUG_SHIRQ=y -+CONFIG_DETECT_HUNG_TASK=y -+CONFIG_SCHEDSTATS=y -+CONFIG_TIMER_STATS=y -+CONFIG_SLUB_DEBUG_ON=y -+CONFIG_DEBUG_RT_MUTEXES=y -+CONFIG_DEBUG_MUTEXES=y -+CONFIG_DEBUG_INFO=y -+CONFIG_DEBUG_LIST=y -+CONFIG_DEBUG_SG=y -+CONFIG_DEBUG_USER=y -+CONFIG_DEBUG_ERRORS=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -diff -Nur linux-3.4.113.orig/arch/nds32/configs/vep-be_defconfig linux-3.4.113/arch/nds32/configs/vep-be_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/vep-be_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/vep-be_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,777 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.29 -+# Mon Jul 13 11:42:57 2009 -+# -+CONFIG_NDS32=y -+CONFIG_NO_IOPORT=y -+CONFIG_GENERIC_IOMAP=y -+CONFIG_RWSEM_GENERIC_SPINLOCK=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_HAVE_LATENCYTOP_SUPPORT=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+# CONFIG_TASKSTATS is not set -+# CONFIG_AUDIT is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_CLASSIC_RCU=y -+# CONFIG_TREE_RCU is not set -+# CONFIG_PREEMPT_RCU is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_PREEMPT_RCU_TRACE is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_GROUP_SCHED is not set -+# CONFIG_CGROUPS is not set -+# CONFIG_SYSFS_DEPRECATED_V2 is not set -+# CONFIG_RELAY is not set -+# CONFIG_NAMESPACES is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_EMBEDDED=y -+CONFIG_UID16=y -+CONFIG_SYSCTL_SYSCALL=y -+# CONFIG_KALLSYMS is not set -+# CONFIG_HOTPLUG is not set -+CONFIG_PRINTK=y -+CONFIG_BUG=y -+# CONFIG_ELF_CORE is not set -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+# CONFIG_SIGNALFD is not set -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_PROFILING=y -+CONFIG_TRACEPOINTS=y -+# CONFIG_MARKERS is not set -+CONFIG_OPROFILE=y -+CONFIG_HAVE_OPROFILE=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_BLK_DEV_BSG is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+# CONFIG_IOSCHED_AS is not set -+# CONFIG_IOSCHED_DEADLINE is not set -+# CONFIG_IOSCHED_CFQ is not set -+# CONFIG_DEFAULT_AS is not set -+# CONFIG_DEFAULT_DEADLINE is not set -+# CONFIG_DEFAULT_CFQ is not set -+CONFIG_DEFAULT_NOOP=y -+CONFIG_DEFAULT_IOSCHED="noop" -+# CONFIG_FREEZER is not set -+ -+# -+# System Type -+# -+# CONFIG_PLAT_FARADAY is not set -+CONFIG_PLAT_VEP=y -+# CONFIG_PLAT_AG101 is not set -+# CONFIG_PLAT_AG102 is not set -+# CONFIG_PLAT_AG101P is not set -+# CONFIG_PLAT_QEMU is not set -+CONFIG_PLATFORM_INTC=y -+ -+# -+# VEP Platform Options -+# -+# CONFIG_CACHE_L2 is not set -+ -+# -+# Common Platform Options -+# -+# CONFIG_PLATFORM_AHBDMA is not set -+# CONFIG_PLATFORM_APBDMA is not set -+CONFIG_SYS_CLK=67737600 -+CONFIG_UART_CLK=36864000 -+CONFIG_SDRAM_SIZE=0x10000000 -+ -+# -+# Processor Features -+# -+CONFIG_CPU_CUSTOM=y -+# CONFIG_FPU is not set -+# CONFIG_AUDIO is not set -+# CONFIG_EVIC is not set -+CONFIG_CPU_CONTEXT_ID=y -+CONFIG_ANDES_PAGE_SIZE_4KB=y -+# CONFIG_ANDES_PAGE_SIZE_8KB is not set -+# CONFIG_KERNEL_SPACE_LARGE_PAGE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -+# CONFIG_ALIGNMENT_TRAP is not set -+CONFIG_MMU=y -+ -+# -+# Kernel Features -+# -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_SELECT_MEMORY_MODEL=y -+CONFIG_FLATMEM_MANUAL=y -+# CONFIG_DISCONTIGMEM_MANUAL is not set -+# CONFIG_SPARSEMEM_MANUAL is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_PAGEFLAGS_EXTENDED=y -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=0 -+CONFIG_VIRT_TO_BUS=y -+CONFIG_UNEVICTABLE_LRU=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_HZ_100=y -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+CONFIG_CMDLINE="root=/dev/ram0 rw mem=64M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" -+ -+# -+# Power management options -+# -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+# CONFIG_PM is not set -+ -+# -+# Bus options -+# -+# CONFIG_PCI is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+ -+# -+# Executable file formats -+# -+CONFIG_BINFMT_ELF=y -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_COMPAT_NET_DEV_OPS=y -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+CONFIG_XFRM=y -+# CONFIG_XFRM_USER is not set -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_IP_ADVANCED_ROUTER is not set -+CONFIG_IP_FIB_HASH=y -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE is not set -+# CONFIG_IP_MROUTE is not set -+# CONFIG_ARPD is not set -+# CONFIG_SYN_COOKIES is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_NET_DSA is not set -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_PHONET is not set -+CONFIG_WIRELESS=y -+# CONFIG_CFG80211 is not set -+CONFIG_WIRELESS_OLD_REGULATORY=y -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_LIB80211 is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+# CONFIG_MTD is not set -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_COW_COMMON is not set -+CONFIG_BLK_DEV_LOOP=y -+# CONFIG_BLK_DEV_CRYPTOLOOP is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+# CONFIG_BLK_DEV_XIP is not set -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_FTSDC010 is not set -+# CONFIG_FTCFC010 is not set -+# CONFIG_BLK_DEV_HD is not set -+# CONFIG_MISC_DEVICES is not set -+CONFIG_HAVE_IDE=y -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+CONFIG_NETDEVICES=y -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_SMC91X is not set -+# CONFIG_DNET is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -+# CONFIG_B44 is not set -+CONFIG_FTMAC100=y -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_IWLWIFI_LEDS is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_JOYDEV is not set -+# CONFIG_INPUT_EVDEV is not set -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+# CONFIG_INPUT_MISC is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_DEVKMEM=y -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_SERIAL_8250_EXTENDED is not set -+ -+# -+# Non-8250 serial port support -+# -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_GPIO_FTGPIO010 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_I2C is not set -+# CONFIG_SPI is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_THERMAL_HWMON is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_REGULATOR is not set -+ -+# -+# Multimedia devices -+# -+ -+# -+# Multimedia core support -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_VIDEO_MEDIA is not set -+ -+# -+# Multimedia drivers -+# -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Console display driver support -+# -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_SOUND is not set -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_RTC_LIB=y -+# CONFIG_RTC_CLASS is not set -+# CONFIG_DMADEVICES is not set -+# CONFIG_UIO is not set -+# CONFIG_STAGING is not set -+ -+# -+# File systems -+# -+CONFIG_EXT2_FS=y -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XIP is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4_FS is not set -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_FS_POSIX_ACL is not set -+CONFIG_FILE_LOCKING=y -+# CONFIG_XFS_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_QUOTA is not set -+# CONFIG_AUTOFS_FS is not set -+# CONFIG_AUTOFS4_FS is not set -+CONFIG_FUSE_FS=y -+ -+# -+# CD-ROM/DVD Filesystems -+# -+# CONFIG_ISO9660_FS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+# CONFIG_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+# CONFIG_PROC_KCORE is not set -+CONFIG_PROC_SYSCTL=y -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE is not set -+# CONFIG_CONFIGFS_FS is not set -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+# CONFIG_CRAMFS is not set -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V3_ACL is not set -+# CONFIG_NFS_V4 is not set -+# CONFIG_NFSD is not set -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+# CONFIG_SUNRPC_REGISTER_V4 is not set -+# CONFIG_RPCSEC_GSS_KRB5 is not set -+# CONFIG_RPCSEC_GSS_SPKM3 is not set -+# CONFIG_SMB_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ASCII is not set -+CONFIG_NLS_ISO8859_1=y -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_UTF8 is not set -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_FRAME_WARN=1024 -+# CONFIG_MAGIC_SYSRQ is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+CONFIG_DEBUG_FS=y -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_KERNEL is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_MEMORY_INIT is not set -+CONFIG_FRAME_POINTER=y -+# CONFIG_RCU_CPU_STALL_DETECTOR is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_SYSCTL_SYSCALL_CHECK=y -+CONFIG_NOP_TRACER=y -+CONFIG_RING_BUFFER=y -+CONFIG_TRACING=y -+ -+# -+# Tracers -+# -+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+CONFIG_DEBUG_USER=y -+# CONFIG_CCTL is not set -+CONFIG_ELFCHK_DEFAULT_ENABLE=y -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+# CONFIG_CRYPTO_FIPS is not set -+# CONFIG_CRYPTO_MANAGER is not set -+# CONFIG_CRYPTO_MANAGER2 is not set -+# CONFIG_CRYPTO_GF128MUL is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+# CONFIG_CRYPTO_CCM is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_SEQIV is not set -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+ -+# -+# Digest -+# -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_MD4 is not set -+# CONFIG_CRYPTO_MD5 is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+# CONFIG_CRYPTO_SHA1 is not set -+# CONFIG_CRYPTO_SHA256 is not set -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+# CONFIG_CRYPTO_AES is not set -+# CONFIG_CRYPTO_ANUBIS is not set -+# CONFIG_CRYPTO_ARC4 is not set -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_LZO is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -+ -+# -+# Library routines -+# -+CONFIG_GENERIC_FIND_LAST_BIT=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_T10DIF is not set -+# CONFIG_CRC_ITU_T is not set -+# CONFIG_CRC32 is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_DMA=y -diff -Nur linux-3.4.113.orig/arch/nds32/configs/vep-le_defconfig linux-3.4.113/arch/nds32/configs/vep-le_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/vep-le_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/vep-le_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,777 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.29 -+# Mon Jul 13 11:41:30 2009 -+# -+CONFIG_NDS32=y -+CONFIG_NO_IOPORT=y -+CONFIG_GENERIC_IOMAP=y -+CONFIG_RWSEM_GENERIC_SPINLOCK=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_HAVE_LATENCYTOP_SUPPORT=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+# CONFIG_TASKSTATS is not set -+# CONFIG_AUDIT is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_CLASSIC_RCU=y -+# CONFIG_TREE_RCU is not set -+# CONFIG_PREEMPT_RCU is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_PREEMPT_RCU_TRACE is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_GROUP_SCHED is not set -+# CONFIG_CGROUPS is not set -+# CONFIG_SYSFS_DEPRECATED_V2 is not set -+# CONFIG_RELAY is not set -+# CONFIG_NAMESPACES is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_EMBEDDED=y -+CONFIG_UID16=y -+CONFIG_SYSCTL_SYSCALL=y -+# CONFIG_KALLSYMS is not set -+# CONFIG_HOTPLUG is not set -+CONFIG_PRINTK=y -+CONFIG_BUG=y -+# CONFIG_ELF_CORE is not set -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+# CONFIG_SIGNALFD is not set -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_PROFILING=y -+CONFIG_TRACEPOINTS=y -+# CONFIG_MARKERS is not set -+CONFIG_OPROFILE=y -+CONFIG_HAVE_OPROFILE=y -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_BLK_DEV_BSG is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+# CONFIG_IOSCHED_AS is not set -+# CONFIG_IOSCHED_DEADLINE is not set -+# CONFIG_IOSCHED_CFQ is not set -+# CONFIG_DEFAULT_AS is not set -+# CONFIG_DEFAULT_DEADLINE is not set -+# CONFIG_DEFAULT_CFQ is not set -+CONFIG_DEFAULT_NOOP=y -+CONFIG_DEFAULT_IOSCHED="noop" -+# CONFIG_FREEZER is not set -+ -+# -+# System Type -+# -+# CONFIG_PLAT_FARADAY is not set -+CONFIG_PLAT_VEP=y -+# CONFIG_PLAT_AG101 is not set -+# CONFIG_PLAT_AG102 is not set -+# CONFIG_PLAT_AG101P is not set -+# CONFIG_PLAT_QEMU is not set -+CONFIG_PLATFORM_INTC=y -+ -+# -+# VEP Platform Options -+# -+# CONFIG_CACHE_L2 is not set -+ -+# -+# Common Platform Options -+# -+# CONFIG_PLATFORM_AHBDMA is not set -+# CONFIG_PLATFORM_APBDMA is not set -+CONFIG_SYS_CLK=67737600 -+CONFIG_UART_CLK=36864000 -+CONFIG_SDRAM_SIZE=0x10000000 -+ -+# -+# Processor Features -+# -+CONFIG_CPU_CUSTOM=y -+# CONFIG_FPU is not set -+# CONFIG_AUDIO is not set -+# CONFIG_EVIC is not set -+CONFIG_CPU_CONTEXT_ID=y -+CONFIG_ANDES_PAGE_SIZE_4KB=y -+# CONFIG_ANDES_PAGE_SIZE_8KB is not set -+# CONFIG_KERNEL_SPACE_LARGE_PAGE is not set -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -+# CONFIG_ALIGNMENT_TRAP is not set -+CONFIG_MMU=y -+ -+# -+# Kernel Features -+# -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_SELECT_MEMORY_MODEL=y -+CONFIG_FLATMEM_MANUAL=y -+# CONFIG_DISCONTIGMEM_MANUAL is not set -+# CONFIG_SPARSEMEM_MANUAL is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_PAGEFLAGS_EXTENDED=y -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=0 -+CONFIG_VIRT_TO_BUS=y -+CONFIG_UNEVICTABLE_LRU=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_HZ_100=y -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+CONFIG_CMDLINE="root=/dev/ram0 rw mem=64M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" -+ -+# -+# Power management options -+# -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+# CONFIG_PM is not set -+ -+# -+# Bus options -+# -+# CONFIG_PCI is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+ -+# -+# Executable file formats -+# -+CONFIG_BINFMT_ELF=y -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_COMPAT_NET_DEV_OPS=y -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+CONFIG_XFRM=y -+# CONFIG_XFRM_USER is not set -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_IP_ADVANCED_ROUTER is not set -+CONFIG_IP_FIB_HASH=y -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE is not set -+# CONFIG_IP_MROUTE is not set -+# CONFIG_ARPD is not set -+# CONFIG_SYN_COOKIES is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_NET_DSA is not set -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_PHONET is not set -+CONFIG_WIRELESS=y -+# CONFIG_CFG80211 is not set -+CONFIG_WIRELESS_OLD_REGULATORY=y -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_LIB80211 is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+# CONFIG_MTD is not set -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_COW_COMMON is not set -+CONFIG_BLK_DEV_LOOP=y -+# CONFIG_BLK_DEV_CRYPTOLOOP is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+# CONFIG_BLK_DEV_XIP is not set -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+# CONFIG_FTSDC010 is not set -+# CONFIG_FTCFC010 is not set -+# CONFIG_BLK_DEV_HD is not set -+# CONFIG_MISC_DEVICES is not set -+CONFIG_HAVE_IDE=y -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+CONFIG_NETDEVICES=y -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_SMC91X is not set -+# CONFIG_DNET is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -+# CONFIG_B44 is not set -+CONFIG_FTMAC100=y -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_IWLWIFI_LEDS is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_JOYDEV is not set -+# CONFIG_INPUT_EVDEV is not set -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+# CONFIG_INPUT_TOUCHSCREEN is not set -+# CONFIG_INPUT_MISC is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_DEVKMEM=y -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_SERIAL_8250_EXTENDED is not set -+ -+# -+# Non-8250 serial port support -+# -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_GPIO_FTGPIO010 is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_I2C is not set -+# CONFIG_SPI is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_THERMAL_HWMON is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_REGULATOR is not set -+ -+# -+# Multimedia devices -+# -+ -+# -+# Multimedia core support -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_VIDEO_MEDIA is not set -+ -+# -+# Multimedia drivers -+# -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+# CONFIG_FB is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Console display driver support -+# -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_DUMMY_CONSOLE=y -+# CONFIG_SOUND is not set -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_RTC_LIB=y -+# CONFIG_RTC_CLASS is not set -+# CONFIG_DMADEVICES is not set -+# CONFIG_UIO is not set -+# CONFIG_STAGING is not set -+ -+# -+# File systems -+# -+CONFIG_EXT2_FS=y -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XIP is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4_FS is not set -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_FS_POSIX_ACL is not set -+CONFIG_FILE_LOCKING=y -+# CONFIG_XFS_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_QUOTA is not set -+# CONFIG_AUTOFS_FS is not set -+# CONFIG_AUTOFS4_FS is not set -+CONFIG_FUSE_FS=y -+ -+# -+# CD-ROM/DVD Filesystems -+# -+# CONFIG_ISO9660_FS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+# CONFIG_MSDOS_FS is not set -+# CONFIG_VFAT_FS is not set -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+# CONFIG_PROC_KCORE is not set -+CONFIG_PROC_SYSCTL=y -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE is not set -+# CONFIG_CONFIGFS_FS is not set -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+# CONFIG_CRAMFS is not set -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V3_ACL is not set -+# CONFIG_NFS_V4 is not set -+# CONFIG_NFSD is not set -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+# CONFIG_SUNRPC_REGISTER_V4 is not set -+# CONFIG_RPCSEC_GSS_KRB5 is not set -+# CONFIG_RPCSEC_GSS_SPKM3 is not set -+# CONFIG_SMB_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ASCII is not set -+CONFIG_NLS_ISO8859_1=y -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_UTF8 is not set -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_FRAME_WARN=1024 -+# CONFIG_MAGIC_SYSRQ is not set -+# CONFIG_UNUSED_SYMBOLS is not set -+CONFIG_DEBUG_FS=y -+# CONFIG_HEADERS_CHECK is not set -+# CONFIG_DEBUG_KERNEL is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_MEMORY_INIT is not set -+CONFIG_FRAME_POINTER=y -+# CONFIG_RCU_CPU_STALL_DETECTOR is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_SYSCTL_SYSCALL_CHECK=y -+CONFIG_NOP_TRACER=y -+CONFIG_RING_BUFFER=y -+CONFIG_TRACING=y -+ -+# -+# Tracers -+# -+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+CONFIG_DEBUG_USER=y -+# CONFIG_CCTL is not set -+CONFIG_ELFCHK_DEFAULT_ENABLE=y -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+# CONFIG_CRYPTO_FIPS is not set -+# CONFIG_CRYPTO_MANAGER is not set -+# CONFIG_CRYPTO_MANAGER2 is not set -+# CONFIG_CRYPTO_GF128MUL is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+# CONFIG_CRYPTO_CCM is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_SEQIV is not set -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+ -+# -+# Digest -+# -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_MD4 is not set -+# CONFIG_CRYPTO_MD5 is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+# CONFIG_CRYPTO_SHA1 is not set -+# CONFIG_CRYPTO_SHA256 is not set -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+# CONFIG_CRYPTO_AES is not set -+# CONFIG_CRYPTO_ANUBIS is not set -+# CONFIG_CRYPTO_ARC4 is not set -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_LZO is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -+ -+# -+# Library routines -+# -+CONFIG_GENERIC_FIND_LAST_BIT=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_T10DIF is not set -+# CONFIG_CRC_ITU_T is not set -+# CONFIG_CRC32 is not set -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_DMA=y -diff -Nur linux-3.4.113.orig/arch/nds32/configs/xc5_8k_defconfig linux-3.4.113/arch/nds32/configs/xc5_8k_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/xc5_8k_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/xc5_8k_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,1051 @@ -+# -+# Automatically generated make config: don't edit -+# Linux kernel version: 2.6.29 -+# Fri Oct 2 14:21:05 2009 -+# -+CONFIG_NDS32=y -+# CONFIG_GENERIC_GPIO is not set -+CONFIG_NO_IOPORT=y -+CONFIG_GENERIC_IOMAP=y -+CONFIG_RWSEM_GENERIC_SPINLOCK=y -+CONFIG_GENERIC_HWEIGHT=y -+CONFIG_GENERIC_FIND_NEXT_BIT=y -+CONFIG_GENERIC_CALIBRATE_DELAY=y -+CONFIG_GENERIC_HARDIRQS=y -+CONFIG_LOCKDEP_SUPPORT=y -+CONFIG_STACKTRACE_SUPPORT=y -+CONFIG_HAVE_LATENCYTOP_SUPPORT=y -+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config" -+ -+# -+# General setup -+# -+CONFIG_EXPERIMENTAL=y -+CONFIG_BROKEN_ON_SMP=y -+CONFIG_INIT_ENV_ARG_LIMIT=32 -+CONFIG_LOCALVERSION="" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SWAP=y -+CONFIG_SYSVIPC=y -+CONFIG_SYSVIPC_SYSCTL=y -+# CONFIG_POSIX_MQUEUE is not set -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+# CONFIG_TASKSTATS is not set -+# CONFIG_AUDIT is not set -+ -+# -+# RCU Subsystem -+# -+CONFIG_CLASSIC_RCU=y -+# CONFIG_TREE_RCU is not set -+# CONFIG_PREEMPT_RCU is not set -+# CONFIG_TREE_RCU_TRACE is not set -+# CONFIG_PREEMPT_RCU_TRACE is not set -+# CONFIG_IKCONFIG is not set -+CONFIG_LOG_BUF_SHIFT=14 -+# CONFIG_GROUP_SCHED is not set -+# CONFIG_CGROUPS is not set -+# CONFIG_SYSFS_DEPRECATED_V2 is not set -+# CONFIG_RELAY is not set -+# CONFIG_NAMESPACES is not set -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="" -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL=y -+CONFIG_ANON_INODES=y -+CONFIG_EMBEDDED=y -+CONFIG_UID16=y -+CONFIG_SYSCTL_SYSCALL=y -+CONFIG_KALLSYMS=y -+# CONFIG_KALLSYMS_ALL is not set -+CONFIG_KALLSYMS_EXTRA_PASS=y -+# CONFIG_HOTPLUG is not set -+CONFIG_PRINTK=y -+CONFIG_BUG=y -+CONFIG_ELF_CORE=y -+CONFIG_BASE_FULL=y -+CONFIG_FUTEX=y -+CONFIG_EPOLL=y -+# CONFIG_SIGNALFD is not set -+CONFIG_TIMERFD=y -+CONFIG_EVENTFD=y -+CONFIG_SHMEM=y -+CONFIG_AIO=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_SLUB_DEBUG=y -+CONFIG_COMPAT_BRK=y -+# CONFIG_SLAB is not set -+CONFIG_SLUB=y -+# CONFIG_SLOB is not set -+CONFIG_PROFILING=y -+CONFIG_TRACEPOINTS=y -+# CONFIG_MARKERS is not set -+CONFIG_OPROFILE=y -+CONFIG_HAVE_OPROFILE=y -+# CONFIG_KPROBES is not set -+CONFIG_HAVE_KPROBES=y -+CONFIG_HAVE_KRETPROBES=y -+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set -+CONFIG_SLABINFO=y -+CONFIG_RT_MUTEXES=y -+CONFIG_BASE_SMALL=0 -+CONFIG_MODULES=y -+# CONFIG_MODULE_FORCE_LOAD is not set -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_MODULE_FORCE_UNLOAD is not set -+# CONFIG_MODVERSIONS is not set -+# CONFIG_MODULE_SRCVERSION_ALL is not set -+CONFIG_BLOCK=y -+# CONFIG_LBD is not set -+# CONFIG_BLK_DEV_IO_TRACE is not set -+# CONFIG_BLK_DEV_BSG is not set -+# CONFIG_BLK_DEV_INTEGRITY is not set -+ -+# -+# IO Schedulers -+# -+CONFIG_IOSCHED_NOOP=y -+CONFIG_IOSCHED_AS=y -+CONFIG_IOSCHED_DEADLINE=y -+CONFIG_IOSCHED_CFQ=y -+# CONFIG_DEFAULT_AS is not set -+# CONFIG_DEFAULT_DEADLINE is not set -+CONFIG_DEFAULT_CFQ=y -+# CONFIG_DEFAULT_NOOP is not set -+CONFIG_DEFAULT_IOSCHED="cfq" -+# CONFIG_FREEZER is not set -+ -+# -+# System Type -+# -+# CONFIG_PLAT_VEP is not set -+# CONFIG_PLAT_AG101 is not set -+# CONFIG_PLAT_AG102 is not set -+CONFIG_PLAT_AG101P=y -+# CONFIG_PLAT_QEMU is not set -+CONFIG_PLATFORM_INTC=y -+CONFIG_ARCH_WANT_OPTIONAL_GPIOLIB=y -+ -+# -+# AG101P Platform Options -+# -+ -+# -+# Common Platform Options -+# -+CONFIG_PLATFORM_AHBDMA=y -+CONFIG_PLATFORM_APBDMA=y -+CONFIG_SYS_CLK=40000000 -+CONFIG_UART_CLK=14745600 -+CONFIG_SDRAM_SIZE=0x10000000 -+ -+# -+# Processor Features -+# -+CONFIG_CPU_CUSTOM=y -+# CONFIG_FPU is not set -+# CONFIG_AUDIO is not set -+# CONFIG_EVIC is not set -+CONFIG_CPU_CONTEXT_ID=y -+# CONFIG_CPU_CACHE_NONALIASING is not set -+# CONFIG_ANDES_PAGE_SIZE_4KB is not set -+CONFIG_ANDES_PAGE_SIZE_8KB=y -+CONFIG_KERNEL_SPACE_LARGE_PAGE=y -+# CONFIG_CPU_ICACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_DISABLE is not set -+# CONFIG_CPU_DCACHE_WRITETHROUGH is not set -+# CONFIG_ABI1 is not set -+CONFIG_ALIGNMENT_TRAP=y -+CONFIG_GENERIC_TIME=y -+CONFIG_GENERIC_CLOCKEVENTS=y -+CONFIG_MMU=y -+ -+# -+# Kernel Features -+# -+# CONFIG_NO_HZ is not set -+# CONFIG_HIGH_RES_TIMERS is not set -+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y -+CONFIG_PREEMPT_NONE=y -+# CONFIG_PREEMPT_VOLUNTARY is not set -+# CONFIG_PREEMPT is not set -+CONFIG_SELECT_MEMORY_MODEL=y -+CONFIG_FLATMEM_MANUAL=y -+# CONFIG_DISCONTIGMEM_MANUAL is not set -+# CONFIG_SPARSEMEM_MANUAL is not set -+CONFIG_FLATMEM=y -+CONFIG_FLAT_NODE_MEM_MAP=y -+CONFIG_PAGEFLAGS_EXTENDED=y -+CONFIG_SPLIT_PTLOCK_CPUS=4 -+# CONFIG_PHYS_ADDR_T_64BIT is not set -+CONFIG_ZONE_DMA_FLAG=0 -+CONFIG_VIRT_TO_BUS=y -+CONFIG_UNEVICTABLE_LRU=y -+CONFIG_FORCE_MAX_ZONEORDER=11 -+CONFIG_HZ_100=y -+# CONFIG_HZ_250 is not set -+# CONFIG_HZ_300 is not set -+# CONFIG_HZ_1000 is not set -+CONFIG_HZ=100 -+# CONFIG_SCHED_HRTICK is not set -+CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" -+ -+# -+# Power management options -+# -+CONFIG_SYS_SUPPORTS_APM_EMULATION=y -+CONFIG_ARCH_SUSPEND_POSSIBLE=y -+# CONFIG_PM is not set -+ -+# -+# Bus options -+# -+# CONFIG_PCI is not set -+# CONFIG_ARCH_SUPPORTS_MSI is not set -+ -+# -+# Executable file formats -+# -+CONFIG_BINFMT_ELF=y -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+# CONFIG_HAVE_AOUT is not set -+# CONFIG_BINFMT_MISC is not set -+CONFIG_NET=y -+ -+# -+# Networking options -+# -+CONFIG_COMPAT_NET_DEV_OPS=y -+CONFIG_PACKET=y -+# CONFIG_PACKET_MMAP is not set -+CONFIG_UNIX=y -+CONFIG_XFRM=y -+# CONFIG_XFRM_USER is not set -+# CONFIG_XFRM_SUB_POLICY is not set -+# CONFIG_XFRM_MIGRATE is not set -+# CONFIG_XFRM_STATISTICS is not set -+CONFIG_NET_KEY=y -+# CONFIG_NET_KEY_MIGRATE is not set -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_IP_ADVANCED_ROUTER is not set -+CONFIG_IP_FIB_HASH=y -+# CONFIG_IP_PNP is not set -+# CONFIG_NET_IPIP is not set -+# CONFIG_NET_IPGRE is not set -+# CONFIG_IP_MROUTE is not set -+# CONFIG_ARPD is not set -+# CONFIG_SYN_COOKIES is not set -+# CONFIG_INET_AH is not set -+# CONFIG_INET_ESP is not set -+# CONFIG_INET_IPCOMP is not set -+# CONFIG_INET_XFRM_TUNNEL is not set -+# CONFIG_INET_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_TCP_CONG_ADVANCED is not set -+CONFIG_TCP_CONG_CUBIC=y -+CONFIG_DEFAULT_TCP_CONG="cubic" -+# CONFIG_TCP_MD5SIG is not set -+# CONFIG_IPV6 is not set -+# CONFIG_NETWORK_SECMARK is not set -+# CONFIG_NETFILTER is not set -+# CONFIG_IP_DCCP is not set -+# CONFIG_IP_SCTP is not set -+# CONFIG_TIPC is not set -+# CONFIG_ATM is not set -+# CONFIG_BRIDGE is not set -+# CONFIG_NET_DSA is not set -+# CONFIG_VLAN_8021Q is not set -+# CONFIG_DECNET is not set -+# CONFIG_LLC2 is not set -+# CONFIG_IPX is not set -+# CONFIG_ATALK is not set -+# CONFIG_X25 is not set -+# CONFIG_LAPB is not set -+# CONFIG_ECONET is not set -+# CONFIG_WAN_ROUTER is not set -+# CONFIG_NET_SCHED is not set -+# CONFIG_DCB is not set -+ -+# -+# Network testing -+# -+# CONFIG_NET_PKTGEN is not set -+# CONFIG_HAMRADIO is not set -+# CONFIG_CAN is not set -+# CONFIG_IRDA is not set -+# CONFIG_BT is not set -+# CONFIG_AF_RXRPC is not set -+# CONFIG_PHONET is not set -+CONFIG_WIRELESS=y -+# CONFIG_CFG80211 is not set -+CONFIG_WIRELESS_OLD_REGULATORY=y -+# CONFIG_WIRELESS_EXT is not set -+# CONFIG_LIB80211 is not set -+# CONFIG_MAC80211 is not set -+# CONFIG_WIMAX is not set -+# CONFIG_RFKILL is not set -+# CONFIG_NET_9P is not set -+ -+# -+# Device Drivers -+# -+ -+# -+# Generic Driver Options -+# -+CONFIG_STANDALONE=y -+CONFIG_PREVENT_FIRMWARE_BUILD=y -+# CONFIG_DEBUG_DRIVER is not set -+# CONFIG_DEBUG_DEVRES is not set -+# CONFIG_SYS_HYPERVISOR is not set -+# CONFIG_CONNECTOR is not set -+CONFIG_MTD=y -+# CONFIG_MTD_DEBUG is not set -+# CONFIG_MTD_CONCAT is not set -+CONFIG_MTD_PARTITIONS=y -+# CONFIG_MTD_TESTS is not set -+# CONFIG_MTD_REDBOOT_PARTS is not set -+CONFIG_MTD_CMDLINE_PARTS=y -+# CONFIG_MTD_AR7_PARTS is not set -+ -+# -+# User Modules And Translation Layers -+# -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLKDEVS=y -+CONFIG_MTD_BLOCK=y -+# CONFIG_FTL is not set -+# CONFIG_NFTL is not set -+# CONFIG_INFTL is not set -+# CONFIG_RFD_FTL is not set -+# CONFIG_SSFDC is not set -+# CONFIG_MTD_OOPS is not set -+ -+# -+# RAM/ROM/Flash chip drivers -+# -+CONFIG_MTD_CFI=y -+# CONFIG_MTD_JEDECPROBE is not set -+CONFIG_MTD_GEN_PROBE=y -+# CONFIG_MTD_CFI_ADV_OPTIONS is not set -+CONFIG_MTD_MAP_BANK_WIDTH_1=y -+CONFIG_MTD_MAP_BANK_WIDTH_2=y -+CONFIG_MTD_MAP_BANK_WIDTH_4=y -+# CONFIG_MTD_MAP_BANK_WIDTH_8 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_16 is not set -+# CONFIG_MTD_MAP_BANK_WIDTH_32 is not set -+CONFIG_MTD_CFI_I1=y -+CONFIG_MTD_CFI_I2=y -+# CONFIG_MTD_CFI_I4 is not set -+# CONFIG_MTD_CFI_I8 is not set -+CONFIG_MTD_CFI_INTELEXT=y -+# CONFIG_MTD_CFI_AMDSTD is not set -+# CONFIG_MTD_CFI_STAA is not set -+CONFIG_MTD_CFI_UTIL=y -+# CONFIG_MTD_RAM is not set -+# CONFIG_MTD_ROM is not set -+# CONFIG_MTD_ABSENT is not set -+ -+# -+# Mapping drivers for chip access -+# -+# CONFIG_MTD_COMPLEX_MAPPINGS is not set -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_PHYSMAP_COMPAT=y -+CONFIG_MTD_PHYSMAP_START=0x80400000 -+CONFIG_MTD_PHYSMAP_LEN=0x2000000 -+CONFIG_MTD_PHYSMAP_BANKWIDTH=4 -+# CONFIG_MTD_PLATRAM is not set -+ -+# -+# Self-contained MTD device drivers -+# -+# CONFIG_MTD_SLRAM is not set -+# CONFIG_MTD_PHRAM is not set -+# CONFIG_MTD_MTDRAM is not set -+# CONFIG_MTD_BLOCK2MTD is not set -+ -+# -+# Disk-On-Chip Device Drivers -+# -+# CONFIG_MTD_DOC2000 is not set -+# CONFIG_MTD_DOC2001 is not set -+# CONFIG_MTD_DOC2001PLUS is not set -+# CONFIG_MTD_NAND is not set -+# CONFIG_MTD_ONENAND is not set -+ -+# -+# LPDDR flash memory drivers -+# -+# CONFIG_MTD_LPDDR is not set -+ -+# -+# UBI - Unsorted block images -+# -+# CONFIG_MTD_UBI is not set -+# CONFIG_PARPORT is not set -+CONFIG_BLK_DEV=y -+# CONFIG_BLK_DEV_COW_COMMON is not set -+CONFIG_BLK_DEV_LOOP=y -+# CONFIG_BLK_DEV_CRYPTOLOOP is not set -+# CONFIG_BLK_DEV_NBD is not set -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_COUNT=16 -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+# CONFIG_BLK_DEV_XIP is not set -+# CONFIG_CDROM_PKTCDVD is not set -+# CONFIG_ATA_OVER_ETH is not set -+CONFIG_FTSDC010=y -+# CONFIG_FTCFC010 is not set -+# CONFIG_BLK_DEV_HD is not set -+# CONFIG_MISC_DEVICES is not set -+CONFIG_HAVE_IDE=y -+# CONFIG_IDE is not set -+ -+# -+# SCSI device support -+# -+# CONFIG_RAID_ATTRS is not set -+# CONFIG_SCSI is not set -+# CONFIG_SCSI_DMA is not set -+# CONFIG_SCSI_NETLINK is not set -+# CONFIG_ATA is not set -+# CONFIG_MD is not set -+CONFIG_NETDEVICES=y -+# CONFIG_DUMMY is not set -+# CONFIG_BONDING is not set -+# CONFIG_MACVLAN is not set -+# CONFIG_EQUALIZER is not set -+# CONFIG_TUN is not set -+# CONFIG_VETH is not set -+# CONFIG_PHYLIB is not set -+CONFIG_NET_ETHERNET=y -+# CONFIG_MII is not set -+# CONFIG_SMC91X is not set -+# CONFIG_DNET is not set -+# CONFIG_IBM_NEW_EMAC_ZMII is not set -+# CONFIG_IBM_NEW_EMAC_RGMII is not set -+# CONFIG_IBM_NEW_EMAC_TAH is not set -+# CONFIG_IBM_NEW_EMAC_EMAC4 is not set -+# CONFIG_IBM_NEW_EMAC_NO_FLOW_CTRL is not set -+# CONFIG_IBM_NEW_EMAC_MAL_CLR_ICINTSTAT is not set -+# CONFIG_IBM_NEW_EMAC_MAL_COMMON_ERR is not set -+# CONFIG_B44 is not set -+CONFIG_FTMAC100=y -+# CONFIG_NETDEV_1000 is not set -+# CONFIG_NETDEV_10000 is not set -+ -+# -+# Wireless LAN -+# -+# CONFIG_WLAN_PRE80211 is not set -+# CONFIG_WLAN_80211 is not set -+# CONFIG_IWLWIFI_LEDS is not set -+ -+# -+# Enable WiMAX (Networking options) to see the WiMAX drivers -+# -+# CONFIG_WAN is not set -+# CONFIG_PPP is not set -+# CONFIG_SLIP is not set -+# CONFIG_NETCONSOLE is not set -+# CONFIG_NETPOLL is not set -+# CONFIG_NET_POLL_CONTROLLER is not set -+# CONFIG_ISDN is not set -+# CONFIG_PHONE is not set -+ -+# -+# Input device support -+# -+CONFIG_INPUT=y -+# CONFIG_INPUT_FF_MEMLESS is not set -+# CONFIG_INPUT_POLLDEV is not set -+ -+# -+# Userland interfaces -+# -+# CONFIG_INPUT_MOUSEDEV is not set -+# CONFIG_INPUT_JOYDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_EVBUG is not set -+ -+# -+# Input Device Drivers -+# -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+# CONFIG_INPUT_JOYSTICK is not set -+# CONFIG_INPUT_TABLET is not set -+CONFIG_INPUT_TOUCHSCREEN=y -+CONFIG_TOUCHSCREEN_CPE_TS=y -+CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER=y -+# CONFIG_TOUCHSCREEN_FUJITSU is not set -+# CONFIG_TOUCHSCREEN_GUNZE is not set -+# CONFIG_TOUCHSCREEN_ELO is not set -+# CONFIG_TOUCHSCREEN_WACOM_W8001 is not set -+# CONFIG_TOUCHSCREEN_MTOUCH is not set -+# CONFIG_TOUCHSCREEN_INEXIO is not set -+# CONFIG_TOUCHSCREEN_MK712 is not set -+# CONFIG_TOUCHSCREEN_PENMOUNT is not set -+# CONFIG_TOUCHSCREEN_TOUCHRIGHT is not set -+# CONFIG_TOUCHSCREEN_TOUCHWIN is not set -+# CONFIG_TOUCHSCREEN_TOUCHIT213 is not set -+# CONFIG_INPUT_MISC is not set -+ -+# -+# Hardware I/O ports -+# -+# CONFIG_SERIO is not set -+# CONFIG_GAMEPORT is not set -+ -+# -+# Character devices -+# -+CONFIG_VT=y -+CONFIG_CONSOLE_TRANSLATIONS=y -+CONFIG_VT_CONSOLE=y -+CONFIG_HW_CONSOLE=y -+# CONFIG_VT_HW_CONSOLE_BINDING is not set -+CONFIG_DEVKMEM=y -+# CONFIG_SERIAL_NONSTANDARD is not set -+ -+# -+# Serial drivers -+# -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_SERIAL_8250_EXTENDED is not set -+ -+# -+# Non-8250 serial port support -+# -+CONFIG_SERIAL_CORE=y -+CONFIG_SERIAL_CORE_CONSOLE=y -+CONFIG_UNIX98_PTYS=y -+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set -+CONFIG_LEGACY_PTYS=y -+CONFIG_LEGACY_PTY_COUNT=256 -+# CONFIG_IPMI_HANDLER is not set -+# CONFIG_HW_RANDOM is not set -+# CONFIG_R3964 is not set -+# CONFIG_GPIO_FTGPIO010_OLD is not set -+# CONFIG_RAW_DRIVER is not set -+# CONFIG_TCG_TPM is not set -+# CONFIG_I2C is not set -+# CONFIG_SPI is not set -+# CONFIG_GPIOLIB is not set -+# CONFIG_W1 is not set -+# CONFIG_POWER_SUPPLY is not set -+# CONFIG_HWMON is not set -+# CONFIG_THERMAL is not set -+# CONFIG_THERMAL_HWMON is not set -+# CONFIG_WATCHDOG is not set -+CONFIG_SSB_POSSIBLE=y -+ -+# -+# Sonics Silicon Backplane -+# -+# CONFIG_SSB is not set -+ -+# -+# Multifunction device drivers -+# -+# CONFIG_MFD_CORE is not set -+# CONFIG_MFD_SM501 is not set -+# CONFIG_HTC_PASIC3 is not set -+# CONFIG_MFD_TMIO is not set -+# CONFIG_REGULATOR is not set -+ -+# -+# Multimedia devices -+# -+ -+# -+# Multimedia core support -+# -+# CONFIG_VIDEO_DEV is not set -+# CONFIG_DVB_CORE is not set -+# CONFIG_VIDEO_MEDIA is not set -+ -+# -+# Multimedia drivers -+# -+# CONFIG_DAB is not set -+ -+# -+# Graphics support -+# -+# CONFIG_VGASTATE is not set -+# CONFIG_VIDEO_OUTPUT_CONTROL is not set -+CONFIG_FB=y -+# CONFIG_FIRMWARE_EDID is not set -+# CONFIG_FB_DDC is not set -+# CONFIG_FB_BOOT_VESA_SUPPORT is not set -+CONFIG_FB_CFB_FILLRECT=y -+CONFIG_FB_CFB_COPYAREA=y -+CONFIG_FB_CFB_IMAGEBLIT=y -+# CONFIG_FB_CFB_REV_PIXELS_IN_BYTE is not set -+# CONFIG_FB_SYS_FILLRECT is not set -+# CONFIG_FB_SYS_COPYAREA is not set -+# CONFIG_FB_SYS_IMAGEBLIT is not set -+# CONFIG_FB_FOREIGN_ENDIAN is not set -+# CONFIG_FB_SYS_FOPS is not set -+# CONFIG_FB_SVGALIB is not set -+# CONFIG_FB_MACMODES is not set -+# CONFIG_FB_BACKLIGHT is not set -+# CONFIG_FB_MODE_HELPERS is not set -+# CONFIG_FB_TILEBLITTING is not set -+ -+# -+# Frame buffer hardware drivers -+# -+# CONFIG_FB_S1D13XXX is not set -+CONFIG_FB_FTLCDC100=y -+CONFIG_PANEL_AUA036QN01=y -+# CONFIG_PANEL_CH7013A is not set -+# CONFIG_PANEL_AUA070VW04 is not set -+# CONFIG_PANEL_LW500AC9601 is not set -+CONFIG_FFB_MODE_RGB=y -+# CONFIG_FFB_MODE_YUV422 is not set -+# CONFIG_FFB_MODE_YUV420 is not set -+# CONFIG_FFB_MODE_8BPP is not set -+CONFIG_FFB_MODE_16BPP=y -+# CONFIG_FFB_MODE_24BPP is not set -+# CONFIG_FB_VIRTUAL is not set -+# CONFIG_FB_METRONOME is not set -+# CONFIG_FB_MB862XX is not set -+# CONFIG_BACKLIGHT_LCD_SUPPORT is not set -+ -+# -+# Display device support -+# -+# CONFIG_DISPLAY_SUPPORT is not set -+ -+# -+# Console display driver support -+# -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_DUMMY_CONSOLE=y -+CONFIG_FRAMEBUFFER_CONSOLE=y -+# CONFIG_FRAMEBUFFER_CONSOLE_DETECT_PRIMARY is not set -+# CONFIG_FRAMEBUFFER_CONSOLE_ROTATION is not set -+# CONFIG_FONTS is not set -+CONFIG_FONT_8x8=y -+CONFIG_FONT_8x16=y -+CONFIG_LOGO=y -+CONFIG_LOGO_LINUX_MONO=y -+CONFIG_LOGO_LINUX_VGA16=y -+CONFIG_LOGO_LINUX_CLUT224=y -+CONFIG_SOUND=y -+CONFIG_SOUND_OSS_CORE=y -+CONFIG_SND=y -+CONFIG_SND_TIMER=y -+CONFIG_SND_PCM=y -+# CONFIG_SND_SEQUENCER is not set -+CONFIG_SND_OSSEMUL=y -+# CONFIG_SND_MIXER_OSS is not set -+CONFIG_SND_PCM_OSS=y -+CONFIG_SND_PCM_OSS_PLUGINS=y -+# CONFIG_SND_DYNAMIC_MINORS is not set -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+# CONFIG_SND_VERBOSE_PRINTK is not set -+# CONFIG_SND_DEBUG is not set -+CONFIG_SND_DRIVERS=y -+# CONFIG_SND_DUMMY is not set -+# CONFIG_SND_MTPAV is not set -+# CONFIG_SND_SERIAL_U16550 is not set -+# CONFIG_SND_MPU401 is not set -+ -+# -+# ALSA NDS32 devices -+# -+CONFIG_SND_FTSSP010=y -+CONFIG_SND_FTSSP010_AC97=y -+# CONFIG_SND_FTSSP010_I2S is not set -+# CONFIG_SND_SOC is not set -+# CONFIG_SOUND_PRIME is not set -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+# CONFIG_MMC is not set -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+# CONFIG_RTC_DEBUG is not set -+ -+# -+# RTC interfaces -+# -+CONFIG_RTC_INTF_SYSFS=y -+CONFIG_RTC_INTF_PROC=y -+CONFIG_RTC_INTF_DEV=y -+# CONFIG_RTC_INTF_DEV_UIE_EMUL is not set -+# CONFIG_RTC_DRV_TEST is not set -+ -+# -+# SPI RTC drivers -+# -+ -+# -+# Platform RTC drivers -+# -+# CONFIG_RTC_DRV_DS1286 is not set -+# CONFIG_RTC_DRV_DS1511 is not set -+# CONFIG_RTC_DRV_DS1553 is not set -+# CONFIG_RTC_DRV_DS1742 is not set -+# CONFIG_RTC_DRV_STK17TA8 is not set -+# CONFIG_RTC_DRV_M48T86 is not set -+# CONFIG_RTC_DRV_M48T35 is not set -+# CONFIG_RTC_DRV_M48T59 is not set -+# CONFIG_RTC_DRV_BQ4802 is not set -+# CONFIG_RTC_DRV_V3020 is not set -+ -+# -+# on-CPU RTC drivers -+# -+CONFIG_RTC_DRV_FTRTC010=y -+# CONFIG_DMADEVICES is not set -+# CONFIG_UIO is not set -+# CONFIG_STAGING is not set -+ -+# -+# File systems -+# -+CONFIG_EXT2_FS=y -+# CONFIG_EXT2_FS_XATTR is not set -+# CONFIG_EXT2_FS_XIP is not set -+# CONFIG_EXT3_FS is not set -+# CONFIG_EXT4_FS is not set -+# CONFIG_REISERFS_FS is not set -+# CONFIG_JFS_FS is not set -+# CONFIG_FS_POSIX_ACL is not set -+CONFIG_FILE_LOCKING=y -+# CONFIG_XFS_FS is not set -+# CONFIG_OCFS2_FS is not set -+# CONFIG_BTRFS_FS is not set -+CONFIG_DNOTIFY=y -+CONFIG_INOTIFY=y -+CONFIG_INOTIFY_USER=y -+# CONFIG_QUOTA is not set -+# CONFIG_AUTOFS_FS is not set -+# CONFIG_AUTOFS4_FS is not set -+CONFIG_FUSE_FS=y -+ -+# -+# CD-ROM/DVD Filesystems -+# -+# CONFIG_ISO9660_FS is not set -+# CONFIG_UDF_FS is not set -+ -+# -+# DOS/FAT/NT Filesystems -+# -+CONFIG_FAT_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+CONFIG_FAT_DEFAULT_CODEPAGE=437 -+CONFIG_FAT_DEFAULT_IOCHARSET="iso8859-1" -+# CONFIG_NTFS_FS is not set -+ -+# -+# Pseudo filesystems -+# -+CONFIG_PROC_FS=y -+# CONFIG_PROC_KCORE is not set -+CONFIG_PROC_SYSCTL=y -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_SYSFS=y -+CONFIG_TMPFS=y -+# CONFIG_TMPFS_POSIX_ACL is not set -+# CONFIG_HUGETLB_PAGE is not set -+# CONFIG_CONFIGFS_FS is not set -+CONFIG_MISC_FILESYSTEMS=y -+# CONFIG_ADFS_FS is not set -+# CONFIG_AFFS_FS is not set -+# CONFIG_HFS_FS is not set -+# CONFIG_HFSPLUS_FS is not set -+# CONFIG_BEFS_FS is not set -+# CONFIG_BFS_FS is not set -+# CONFIG_EFS_FS is not set -+CONFIG_JFFS2_FS=y -+CONFIG_JFFS2_FS_DEBUG=0 -+CONFIG_JFFS2_FS_WRITEBUFFER=y -+# CONFIG_JFFS2_FS_WBUF_VERIFY is not set -+# CONFIG_JFFS2_SUMMARY is not set -+# CONFIG_JFFS2_FS_XATTR is not set -+# CONFIG_JFFS2_COMPRESSION_OPTIONS is not set -+CONFIG_JFFS2_ZLIB=y -+# CONFIG_JFFS2_LZO is not set -+CONFIG_JFFS2_RTIME=y -+# CONFIG_JFFS2_RUBIN is not set -+# CONFIG_CRAMFS is not set -+# CONFIG_SQUASHFS is not set -+# CONFIG_VXFS_FS is not set -+# CONFIG_MINIX_FS is not set -+# CONFIG_OMFS_FS is not set -+# CONFIG_HPFS_FS is not set -+# CONFIG_QNX4FS_FS is not set -+# CONFIG_ROMFS_FS is not set -+# CONFIG_SYSV_FS is not set -+# CONFIG_UFS_FS is not set -+CONFIG_NETWORK_FILESYSTEMS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+# CONFIG_NFS_V3_ACL is not set -+# CONFIG_NFS_V4 is not set -+# CONFIG_NFSD is not set -+CONFIG_LOCKD=y -+CONFIG_LOCKD_V4=y -+CONFIG_NFS_COMMON=y -+CONFIG_SUNRPC=y -+# CONFIG_SUNRPC_REGISTER_V4 is not set -+# CONFIG_RPCSEC_GSS_KRB5 is not set -+# CONFIG_RPCSEC_GSS_SPKM3 is not set -+# CONFIG_SMB_FS is not set -+# CONFIG_CIFS is not set -+# CONFIG_NCP_FS is not set -+# CONFIG_CODA_FS is not set -+# CONFIG_AFS_FS is not set -+ -+# -+# Partition Types -+# -+# CONFIG_PARTITION_ADVANCED is not set -+CONFIG_MSDOS_PARTITION=y -+CONFIG_NLS=y -+CONFIG_NLS_DEFAULT="iso8859-1" -+CONFIG_NLS_CODEPAGE_437=y -+# CONFIG_NLS_CODEPAGE_737 is not set -+# CONFIG_NLS_CODEPAGE_775 is not set -+# CONFIG_NLS_CODEPAGE_850 is not set -+# CONFIG_NLS_CODEPAGE_852 is not set -+# CONFIG_NLS_CODEPAGE_855 is not set -+# CONFIG_NLS_CODEPAGE_857 is not set -+# CONFIG_NLS_CODEPAGE_860 is not set -+# CONFIG_NLS_CODEPAGE_861 is not set -+# CONFIG_NLS_CODEPAGE_862 is not set -+# CONFIG_NLS_CODEPAGE_863 is not set -+# CONFIG_NLS_CODEPAGE_864 is not set -+# CONFIG_NLS_CODEPAGE_865 is not set -+# CONFIG_NLS_CODEPAGE_866 is not set -+# CONFIG_NLS_CODEPAGE_869 is not set -+# CONFIG_NLS_CODEPAGE_936 is not set -+# CONFIG_NLS_CODEPAGE_950 is not set -+# CONFIG_NLS_CODEPAGE_932 is not set -+# CONFIG_NLS_CODEPAGE_949 is not set -+# CONFIG_NLS_CODEPAGE_874 is not set -+# CONFIG_NLS_ISO8859_8 is not set -+# CONFIG_NLS_CODEPAGE_1250 is not set -+# CONFIG_NLS_CODEPAGE_1251 is not set -+# CONFIG_NLS_ASCII is not set -+CONFIG_NLS_ISO8859_1=y -+# CONFIG_NLS_ISO8859_2 is not set -+# CONFIG_NLS_ISO8859_3 is not set -+# CONFIG_NLS_ISO8859_4 is not set -+# CONFIG_NLS_ISO8859_5 is not set -+# CONFIG_NLS_ISO8859_6 is not set -+# CONFIG_NLS_ISO8859_7 is not set -+# CONFIG_NLS_ISO8859_9 is not set -+# CONFIG_NLS_ISO8859_13 is not set -+# CONFIG_NLS_ISO8859_14 is not set -+# CONFIG_NLS_ISO8859_15 is not set -+# CONFIG_NLS_KOI8_R is not set -+# CONFIG_NLS_KOI8_U is not set -+# CONFIG_NLS_UTF8 is not set -+# CONFIG_DLM is not set -+ -+# -+# Kernel hacking -+# -+CONFIG_TRACE_IRQFLAGS_SUPPORT=y -+# CONFIG_PRINTK_TIME is not set -+CONFIG_ENABLE_WARN_DEPRECATED=y -+CONFIG_ENABLE_MUST_CHECK=y -+CONFIG_FRAME_WARN=1024 -+CONFIG_MAGIC_SYSRQ=y -+# CONFIG_UNUSED_SYMBOLS is not set -+CONFIG_DEBUG_FS=y -+# CONFIG_HEADERS_CHECK is not set -+CONFIG_DEBUG_KERNEL=y -+CONFIG_DEBUG_SHIRQ=y -+CONFIG_DETECT_SOFTLOCKUP=y -+# CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC is not set -+CONFIG_BOOTPARAM_SOFTLOCKUP_PANIC_VALUE=0 -+CONFIG_SCHED_DEBUG=y -+CONFIG_SCHEDSTATS=y -+CONFIG_TIMER_STATS=y -+# CONFIG_DEBUG_OBJECTS is not set -+# CONFIG_SLUB_DEBUG_ON is not set -+# CONFIG_SLUB_STATS is not set -+CONFIG_DEBUG_RT_MUTEXES=y -+CONFIG_DEBUG_PI_LIST=y -+# CONFIG_RT_MUTEX_TESTER is not set -+CONFIG_DEBUG_SPINLOCK=y -+CONFIG_DEBUG_MUTEXES=y -+# CONFIG_DEBUG_LOCK_ALLOC is not set -+# CONFIG_PROVE_LOCKING is not set -+# CONFIG_LOCK_STAT is not set -+CONFIG_DEBUG_SPINLOCK_SLEEP=y -+# CONFIG_DEBUG_LOCKING_API_SELFTESTS is not set -+CONFIG_STACKTRACE=y -+# CONFIG_DEBUG_KOBJECT is not set -+CONFIG_DEBUG_INFO=y -+# CONFIG_DEBUG_VM is not set -+# CONFIG_DEBUG_WRITECOUNT is not set -+# CONFIG_DEBUG_MEMORY_INIT is not set -+CONFIG_DEBUG_LIST=y -+CONFIG_DEBUG_SG=y -+# CONFIG_DEBUG_NOTIFIERS is not set -+CONFIG_FRAME_POINTER=y -+# CONFIG_BOOT_PRINTK_DELAY is not set -+# CONFIG_RCU_TORTURE_TEST is not set -+# CONFIG_RCU_CPU_STALL_DETECTOR is not set -+# CONFIG_BACKTRACE_SELF_TEST is not set -+# CONFIG_DEBUG_BLOCK_EXT_DEVT is not set -+# CONFIG_FAULT_INJECTION is not set -+# CONFIG_LATENCYTOP is not set -+CONFIG_SYSCTL_SYSCALL_CHECK=y -+CONFIG_NOP_TRACER=y -+CONFIG_RING_BUFFER=y -+CONFIG_TRACING=y -+ -+# -+# Tracers -+# -+# CONFIG_IRQSOFF_TRACER is not set -+# CONFIG_SCHED_TRACER is not set -+# CONFIG_CONTEXT_SWITCH_TRACER is not set -+# CONFIG_BOOT_TRACER is not set -+# CONFIG_TRACE_BRANCH_PROFILING is not set -+# CONFIG_FTRACE_STARTUP_TEST is not set -+# CONFIG_DYNAMIC_PRINTK_DEBUG is not set -+# CONFIG_SAMPLES is not set -+CONFIG_HAVE_ARCH_KGDB=y -+# CONFIG_KGDB is not set -+CONFIG_DEBUG_USER=y -+CONFIG_DEBUG_ERRORS=y -+# CONFIG_DEBUG_LL is not set -+# CONFIG_CCTL is not set -+# CONFIG_ELFCHK_DEFAULT_ENABLE is not set -+ -+# -+# Security options -+# -+# CONFIG_KEYS is not set -+# CONFIG_SECURITY is not set -+# CONFIG_SECURITYFS is not set -+# CONFIG_SECURITY_FILE_CAPABILITIES is not set -+CONFIG_CRYPTO=y -+ -+# -+# Crypto core or helper -+# -+# CONFIG_CRYPTO_FIPS is not set -+# CONFIG_CRYPTO_MANAGER is not set -+# CONFIG_CRYPTO_MANAGER2 is not set -+# CONFIG_CRYPTO_GF128MUL is not set -+# CONFIG_CRYPTO_NULL is not set -+# CONFIG_CRYPTO_CRYPTD is not set -+# CONFIG_CRYPTO_AUTHENC is not set -+# CONFIG_CRYPTO_TEST is not set -+ -+# -+# Authenticated Encryption with Associated Data -+# -+# CONFIG_CRYPTO_CCM is not set -+# CONFIG_CRYPTO_GCM is not set -+# CONFIG_CRYPTO_SEQIV is not set -+ -+# -+# Block modes -+# -+# CONFIG_CRYPTO_CBC is not set -+# CONFIG_CRYPTO_CTR is not set -+# CONFIG_CRYPTO_CTS is not set -+# CONFIG_CRYPTO_ECB is not set -+# CONFIG_CRYPTO_LRW is not set -+# CONFIG_CRYPTO_PCBC is not set -+# CONFIG_CRYPTO_XTS is not set -+ -+# -+# Hash modes -+# -+# CONFIG_CRYPTO_HMAC is not set -+# CONFIG_CRYPTO_XCBC is not set -+ -+# -+# Digest -+# -+# CONFIG_CRYPTO_CRC32C is not set -+# CONFIG_CRYPTO_MD4 is not set -+# CONFIG_CRYPTO_MD5 is not set -+# CONFIG_CRYPTO_MICHAEL_MIC is not set -+# CONFIG_CRYPTO_RMD128 is not set -+# CONFIG_CRYPTO_RMD160 is not set -+# CONFIG_CRYPTO_RMD256 is not set -+# CONFIG_CRYPTO_RMD320 is not set -+# CONFIG_CRYPTO_SHA1 is not set -+# CONFIG_CRYPTO_SHA256 is not set -+# CONFIG_CRYPTO_SHA512 is not set -+# CONFIG_CRYPTO_TGR192 is not set -+# CONFIG_CRYPTO_WP512 is not set -+ -+# -+# Ciphers -+# -+# CONFIG_CRYPTO_AES is not set -+# CONFIG_CRYPTO_ANUBIS is not set -+# CONFIG_CRYPTO_ARC4 is not set -+# CONFIG_CRYPTO_BLOWFISH is not set -+# CONFIG_CRYPTO_CAMELLIA is not set -+# CONFIG_CRYPTO_CAST5 is not set -+# CONFIG_CRYPTO_CAST6 is not set -+# CONFIG_CRYPTO_DES is not set -+# CONFIG_CRYPTO_FCRYPT is not set -+# CONFIG_CRYPTO_KHAZAD is not set -+# CONFIG_CRYPTO_SALSA20 is not set -+# CONFIG_CRYPTO_SEED is not set -+# CONFIG_CRYPTO_SERPENT is not set -+# CONFIG_CRYPTO_TEA is not set -+# CONFIG_CRYPTO_TWOFISH is not set -+ -+# -+# Compression -+# -+# CONFIG_CRYPTO_DEFLATE is not set -+# CONFIG_CRYPTO_LZO is not set -+ -+# -+# Random Number Generation -+# -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -+ -+# -+# Library routines -+# -+CONFIG_BITREVERSE=y -+CONFIG_GENERIC_FIND_LAST_BIT=y -+# CONFIG_CRC_CCITT is not set -+# CONFIG_CRC16 is not set -+# CONFIG_CRC_T10DIF is not set -+# CONFIG_CRC_ITU_T is not set -+CONFIG_CRC32=y -+# CONFIG_CRC7 is not set -+# CONFIG_LIBCRC32C is not set -+CONFIG_ZLIB_INFLATE=y -+CONFIG_ZLIB_DEFLATE=y -+CONFIG_PLIST=y -+CONFIG_HAS_IOMEM=y -+CONFIG_HAS_DMA=y -diff -Nur linux-3.4.113.orig/arch/nds32/configs/xc5_defconfig linux-3.4.113/arch/nds32/configs/xc5_defconfig ---- linux-3.4.113.orig/arch/nds32/configs/xc5_defconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/configs/xc5_defconfig 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,117 @@ -+CONFIG_EXPERIMENTAL=y -+CONFIG_CROSS_COMPILE="nds32le-linux-" -+# CONFIG_LOCALVERSION_AUTO is not set -+CONFIG_SYSVIPC=y -+CONFIG_BSD_PROCESS_ACCT=y -+CONFIG_BSD_PROCESS_ACCT_V3=y -+CONFIG_IKCONFIG=y -+CONFIG_IKCONFIG_PROC=y -+CONFIG_LOG_BUF_SHIFT=14 -+CONFIG_BLK_DEV_INITRD=y -+CONFIG_INITRAMFS_SOURCE="/home/users/greentime/os/ramdisk/disk-nds32le-linux-glibc-v3 /home/users/greentime/os/ramdisk/disk-nds32le-linux-glibc-v3/dev/initramfs.devnodes" -+CONFIG_CC_OPTIMIZE_FOR_SIZE=y -+CONFIG_SYSCTL_SYSCALL=y -+# CONFIG_HOTPLUG is not set -+# CONFIG_SIGNALFD is not set -+CONFIG_EMBEDDED=y -+# CONFIG_VM_EVENT_COUNTERS is not set -+CONFIG_PROFILING=y -+CONFIG_OPROFILE=y -+CONFIG_MODULES=y -+CONFIG_MODULE_UNLOAD=y -+# CONFIG_BLK_DEV_BSG is not set -+CONFIG_PLATFORM_AHBDMA=y -+CONFIG_PLATFORM_APBDMA=y -+CONFIG_SYS_CLK=30000000 -+CONFIG_UART_CLK=14745600 -+CONFIG_SDRAM_SIZE=0x8000000 -+CONFIG_HZ_100=y -+CONFIG_CMDLINE="root=/dev/ram0 rw mem=128M@0x0 initrd=0x1000000,8M console=ttyS0,38400n8 earlyprintk=uart8250-32bit,0x99600000 rootfstype=ext2 init=/bin/busybox init -s user_debug=-1" -+# CONFIG_CORE_DUMP_DEFAULT_ELF_HEADERS is not set -+CONFIG_NET=y -+CONFIG_PACKET=y -+CONFIG_UNIX=y -+CONFIG_NET_KEY=y -+CONFIG_INET=y -+CONFIG_IP_MULTICAST=y -+# CONFIG_INET_XFRM_MODE_TRANSPORT is not set -+# CONFIG_INET_XFRM_MODE_TUNNEL is not set -+# CONFIG_INET_XFRM_MODE_BEET is not set -+# CONFIG_INET_LRO is not set -+# CONFIG_INET_DIAG is not set -+# CONFIG_IPV6 is not set -+CONFIG_BRIDGE=y -+CONFIG_MTD=y -+CONFIG_MTD_CMDLINE_PARTS=y -+CONFIG_MTD_CHAR=y -+CONFIG_MTD_BLOCK=y -+CONFIG_MTD_CFI=y -+CONFIG_MTD_CFI_INTELEXT=y -+CONFIG_MTD_PHYSMAP=y -+CONFIG_MTD_PHYSMAP_COMPAT=y -+CONFIG_MTD_PHYSMAP_START=0x80400000 -+CONFIG_MTD_PHYSMAP_LEN=0x2000000 -+CONFIG_MTD_PHYSMAP_BANKWIDTH=4 -+CONFIG_BLK_DEV_LOOP=y -+CONFIG_BLK_DEV_RAM=y -+CONFIG_BLK_DEV_RAM_SIZE=8192 -+CONFIG_NETDEVICES=y -+CONFIG_TUN=y -+CONFIG_FTMAC100=y -+# CONFIG_INPUT_MOUSEDEV is not set -+CONFIG_INPUT_EVDEV=y -+# CONFIG_INPUT_KEYBOARD is not set -+# CONFIG_INPUT_MOUSE is not set -+CONFIG_INPUT_TOUCHSCREEN=y -+# CONFIG_SERIO is not set -+CONFIG_SERIAL_8250=y -+CONFIG_SERIAL_8250_CONSOLE=y -+CONFIG_SERIAL_8250_NR_UARTS=3 -+CONFIG_SERIAL_8250_RUNTIME_UARTS=3 -+# CONFIG_HW_RANDOM is not set -+# CONFIG_HWMON is not set -+CONFIG_FB=y -+# CONFIG_VGA_CONSOLE is not set -+CONFIG_FRAMEBUFFER_CONSOLE=y -+CONFIG_LOGO=y -+CONFIG_SOUND=y -+CONFIG_SND=y -+CONFIG_SND_PCM_OSS=y -+# CONFIG_SND_SUPPORT_OLD_API is not set -+# CONFIG_SND_VERBOSE_PROCFS is not set -+# CONFIG_HID_SUPPORT is not set -+# CONFIG_USB_SUPPORT is not set -+CONFIG_MMC=y -+CONFIG_MMC_FTSDC010=y -+# CONFIG_MEMSTICK is not set -+# CONFIG_NEW_LEDS is not set -+# CONFIG_ACCESSIBILITY is not set -+CONFIG_RTC_LIB=y -+CONFIG_RTC_CLASS=y -+# CONFIG_RTC_HCTOSYS is not set -+CONFIG_EXT2_FS=y -+CONFIG_FUSE_FS=y -+CONFIG_MSDOS_FS=y -+CONFIG_VFAT_FS=y -+# CONFIG_PROC_PAGE_MONITOR is not set -+CONFIG_TMPFS=y -+CONFIG_JFFS2_FS=y -+CONFIG_NFS_FS=y -+CONFIG_NFS_V3=y -+CONFIG_NLS_CODEPAGE_437=y -+CONFIG_NLS_ISO8859_1=y -+CONFIG_MAGIC_SYSRQ=y -+CONFIG_DEBUG_FS=y -+CONFIG_DEBUG_SHIRQ=y -+CONFIG_SCHEDSTATS=y -+CONFIG_TIMER_STATS=y -+CONFIG_DEBUG_RT_MUTEXES=y -+CONFIG_DEBUG_SPINLOCK=y -+CONFIG_DEBUG_MUTEXES=y -+CONFIG_DEBUG_INFO=y -+CONFIG_DEBUG_LIST=y -+CONFIG_DEBUG_SG=y -+CONFIG_DEBUG_USER=y -+CONFIG_DEBUG_ERRORS=y -+# CONFIG_CRYPTO_ANSI_CPRNG is not set -+# CONFIG_CRYPTO_HW is not set -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/amic.h linux-3.4.113/arch/nds32/include/asm/amic.h ---- linux-3.4.113.orig/arch/nds32/include/asm/amic.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/amic.h 2016-12-01 20:59:24.328611826 +0100 -@@ -0,0 +1,60 @@ -+/* -+ * linux/arch/nds32/include/asm/amic.h -+ * -+ * Andes Multi-core Interrupt Controller Device Driver Interface -+ * -+ * Copyright (C) 2010 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Shawn Lin 09/02/2010 Created for Andes AG102 platform code. -+ */ -+ -+#ifndef __NDS32_AMIC_HEADER__ -+#define __NDS32_AMIC_HEADER__ -+ -+#define IRQ_BASE 0x0 -+#define IRQ_TOTAL 0x20 -+#define DEFAULT_MODE 0x000ecc00 -+#define DEFAULT_LEVEL 0xffffffff -+#define AMIC_BASE AMIC_VA_BASE -+#define CONFIG 0x00 -+#define CPUDC 0x04 -+#define CPUID0 0x08 -+#define CPUID1 0x0c -+#define INTTRG 0x20 -+#define INTLVL 0x24 -+#define INTSRC 0x28 -+#define IPITRG 0x40 -+#define IPISTA 0x44 -+#define IPIPTR 0x48 -+#define IPIGST 0x4c -+#define IPIGPT 0x50 -+#define INTEN 0x80 -+#define INTSTA 0x84 -+#define HW0STA 0x88 -+#define HW1STA 0x8c -+#define HW2STA 0x90 -+#define HW3STA 0x94 -+#define HW4STA 0x98 -+#define HW5STA 0x9c -+#define PRITY0 0xa0 -+#define PRITY1 0xa4 -+#define PRITY2 0xa8 -+#define PRITY3 0xac -+ -+#endif /* __NDS32_AMIC_HEADER__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/asm-offsets.h linux-3.4.113/arch/nds32/include/asm/asm-offsets.h ---- linux-3.4.113.orig/arch/nds32/include/asm/asm-offsets.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/asm-offsets.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1 @@ -+#include -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/assembler.h linux-3.4.113/arch/nds32/include/asm/assembler.h ---- linux-3.4.113.orig/arch/nds32/include/asm/assembler.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/assembler.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,141 @@ -+/* -+ * linux/arch/nds32/include/asm/assembler.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_ASSEMBLER_H__ -+#define __NDS32_ASSEMBLER_H__ -+ -+/* -+ * Stack format -+ */ -+ -+#define S_PAD 0xac /* Padding for stack pointer 8-byte alignment. */ -+#define S_FUCOP_CTL 0xa8 -+#define S_LP 0xa4 -+#define S_GP 0xa0 -+#define S_FP 0x9c -+#define S_R25 0x98 -+#define S_R24 0x94 -+#define S_R23 0x90 -+#define S_R22 0x8c -+#define S_R21 0x88 -+#define S_R20 0x84 -+#define S_R19 0x80 -+#define S_R18 0x7c -+#define S_R17 0x78 -+#define S_R16 0x74 -+#define S_R15 0x70 -+#define S_R14 0x6c -+#define S_R13 0x68 -+#define S_R12 0x64 -+#define S_R11 0x60 -+#define S_R10 0x5c -+#define S_R9 0x58 -+#define S_R8 0x54 -+#define S_R7 0x50 -+#define S_R6 0x4c -+#define S_R5 0x48 -+#define S_R4 0x44 -+#define S_R3 0x40 -+#define S_R2 0x3c -+#define S_R1 0x38 -+#define S_R0 0x34 -+#define S_D1LO 0x30 -+#define S_D1HI 0x2c -+#define S_D0LO 0x28 -+#define S_D0HI 0x24 -+#define S_PP1 0x20 -+#define S_PP0 0x1c -+#define S_PIPC 0x18 -+#define S_PIPSW 0x14 -+#define S_ORIG_R0 0x10 -+#define S_SP 0xc -+#define S_IPC 0x8 -+#define S_IPSW 0x4 -+#define S_IR0 0x0 -+ -+#if !defined(CONFIG_ABI1) -+#define S_OFF 0 -+#else -+#define S_OFF 24 -+#endif -+ -+#ifdef __ASSEMBLY__ -+.macro get_thread_info, rd -+ srli \rd, $sp, #13 -+ slli \rd, \rd, #13 -+.endm -+ -+.macro gie_disable -+ setgie.d -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ isb -+#else -+ dsb -+#endif -+.endm -+ -+.macro gie_enable -+ setgie.e -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ isb -+#else -+ dsb -+#endif -+.endm -+ -+.macro gie_save oldpsw -+ mfsr \oldpsw, $ir0 -+ setgie.d -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ isb -+#else -+ dsb -+#endif -+.endm -+ -+.macro gie_restore oldpsw -+ andi \oldpsw, \oldpsw, #0x1 -+ beqz \oldpsw, 7001f -+ setgie.e -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ isb -+#else -+ dsb -+#endif -+7001: -+.endm -+ -+ -+#define USER(insn, reg, addr, opr) \ -+9999: insn reg, addr, opr; \ -+ .section __ex_table,"a"; \ -+ .align 3; \ -+ .long 9999b, 9001f; \ -+ .previous -+ -+#else /* __ASSEMBLY__ */ -+ -+__asm__ (".macro gie_disable\n\t" -+ "setgie.d\n\t" -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ "isb\n\t" -+#else -+ "dsb\n\t" -+#endif -+ ".endm\n\t" -+ ); -+ -+__asm__ (".macro gie_enable\n\t" -+ "setgie.e\n\t" -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ "isb\n\t" -+#else -+ "dsb\n\t" -+#endif -+ ".endm\n\t" -+ ); -+ -+#endif /* !__ASSEMBLY__ */ -+#endif /* __NDS32_ASSEMBLER_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/atomic.h linux-3.4.113/arch/nds32/include/asm/atomic.h ---- linux-3.4.113.orig/arch/nds32/include/asm/atomic.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/atomic.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,267 @@ -+/* -+ * linux/arch/nds32/include/asm/atomic.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_ATOMIC_H__ -+#define __NDS32_ATOMIC_H__ -+ -+#include -+#include -+#include -+ -+#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) -+ -+#define ATOMIC_INIT(i) { (i) } -+#define atomic_set(v,i) (((v)->counter) = (i)) -+#define atomic_read(v) (*(volatile int *)&(v)->counter) -+ -+static inline void atomic_add(int i, atomic_t *v) -+{ -+ int temp; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tadd\t%0, %0, %2\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (temp) : "r" (&v->counter), "r" (i)); -+} -+ -+static inline void atomic_sub(int i, atomic_t *v) -+{ -+ int temp; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tsub\t%0, %0, %2\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (temp) : "r" (&v->counter), "r" (i)); -+} -+ -+#define atomic_inc(v) atomic_add(1, v) -+#define atomic_dec(v) atomic_sub(1, v) -+ -+static inline int atomic_inc_return(atomic_t *v) -+{ -+ int temp1, temp2; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\taddi\t%1, %1, #1\n" -+ "\tori\t%0, %1, #0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter)); -+ return temp2; -+} -+ -+static inline int atomic_dec_return(atomic_t *v) -+{ -+ int temp1, temp2; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\taddi\t%1, %1, #-1\n" -+ "\tori\t%0, %1, #0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter)); -+ return temp2; -+} -+ -+static inline int atomic_add_return(int i, atomic_t *v) -+{ -+ int temp1, temp2; -+ -+ smp_mb(); -+ -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\tadd\t%1, %1, %3\n" -+ "\tori\t%0, %1, #0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter), "r" (i)); -+ -+ smp_mb(); -+ -+ return temp2; -+} -+ -+static inline int atomic_sub_return(int i, atomic_t *v) -+{ -+ int temp1, temp2; -+ -+ smp_mb(); -+ -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\tsub\t%1, %1, %3\n" -+ "\tori\t%0, %1, #0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter), "r" (i)); -+ -+ smp_mb(); -+ -+ return temp2; -+} -+ -+/* -+ * atomic_dec_if_positive - conditionally subtract one from atomic variable -+ * @v: pointer of type atomic_t -+ * -+ * Atomically test @v and subtract one if @v is greater or equal than one. -+ * The function returns the old value of @v minus one. -+ */ -+static inline int atomic_dec_if_positive(atomic_t * v) -+{ -+ int temp1, temp2, temp3; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%2, [%3+$r15]\n" -+ "\taddi\t%0, %2, #-1\n" -+ "\tslts\t%1, $r15, %2\n" -+ "\tsub\t%2, %2, %1\n" -+ "\tscw\t%2, [%3+$r15]\n" -+ "\tbeqz\t%2, 1b\n" -+ : "=&r" (temp3), "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter)); -+ return temp3; -+} -+ -+ -+#define atomic_inc_and_test(v) (atomic_add_return(1, v) == 0) -+#define atomic_dec_and_test(v) (atomic_sub_return(1, v) == 0) -+#define atomic_sub_and_test(i,v) (atomic_sub_return((i),(v)) == 0) -+#define atomic_add_negative(i,v) (atomic_add_return((i),(v)) < 0) -+ -+ -+static inline int atomic_cmpxchg(atomic_t *v, int old, int new) -+{ -+ int temp1, temp2, temp3; -+ -+ smp_mb(); -+ -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%0, [%3+$r15]\n" -+ "\tsub\t%2, %0, %5\n" -+ "\tcmovz\t%1, %4, %2\n" -+ "\tcmovn\t%1, %0, %2\n" -+ "\tscw\t%1, [%3+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp3), "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter), "r" (new), "r" (old)); -+ -+ smp_mb(); -+ -+ return temp3; -+} -+ -+static inline int atomic_xchg(atomic_t *v, int new) -+{ -+ int temp1, temp2; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%0, [%2+$r15]\n" -+ "\tori\t%1, %3, #0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter), "r" (new)); -+ return temp2; -+} -+ -+static inline int __atomic_add_unless(atomic_t *v, int a, int u) -+{ -+ int c, old; -+ -+ c = atomic_read(v); -+ while (c != u && (old = atomic_cmpxchg((v), c, c + a)) != c) -+ c = old; -+ return c; -+} -+ -+static inline int atomic_inc_not_zero(atomic_t *v) -+{ -+ int temp1, temp2; -+ __asm__ __volatile__( -+ "movi\t$r15, #0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\tslt\t%0, $r15, %1\n" -+ "\tadd\t%1, %1, %0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (temp2), "=&r" (temp1) -+ : "r" (&v->counter)); -+ return temp2; -+} -+ -+#define smp_mb__before_atomic_dec() barrier() -+#define smp_mb__after_atomic_dec() barrier() -+#define smp_mb__before_atomic_inc() barrier() -+#define smp_mb__after_atomic_inc() barrier() -+ -+//#include -+#else /* CONFIG_SMP*/ -+ -+ -+ -+#define ATOMIC_INIT(i) { (i) } -+ -+#ifdef __KERNEL__ -+ -+#include -+ -+static inline int atomic_dec_if_positive(atomic_t * v) -+{ -+ unsigned long flags; -+ int result; -+ -+ local_irq_save(flags); -+ result = v->counter; -+ result -= 1; -+ if (result >= 0) -+ v->counter = result; -+ local_irq_restore(flags); -+ return result; -+} -+ -+/* Atomic operations are already serializing on ARM */ -+#define smp_mb__before_atomic_dec() barrier() -+#define smp_mb__after_atomic_dec() barrier() -+#define smp_mb__before_atomic_inc() barrier() -+#define smp_mb__after_atomic_inc() barrier() -+ -+#endif -+ -+#endif /* CONFIG_SMP */ -+ -+#ifndef CONFIG_GENERIC_ATOMIC64 -+typedef struct { -+ u64 __aligned(8) counter; -+} atomic64_t; -+#define ATOMIC64_INIT(i) { (i) } -+static inline u64 atomic64_add_return(u64 i, atomic64_t *v){ return 0; } -+#endif /* CONFIG_GENERIC_ATOMIC64 */ -+ -+#endif /* __NDS32_ATOMIC_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/audio.h linux-3.4.113/arch/nds32/include/asm/audio.h ---- linux-3.4.113.orig/arch/nds32/include/asm/audio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/audio.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,65 @@ -+/* -+ * linux/arch/nds32/include/asm/audio.h -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_AUDIO_H -+#define __ASM_NDS32_AUDIO_H -+ -+#ifndef __ASSEMBLY__ -+#include -+#include -+ -+extern void save_audio(struct task_struct *tsk); -+extern void audioload(struct audio_struct *audioregs); -+extern void save_audio(struct task_struct *__tsk); -+extern void do_audio_context_switch(unsigned long error_code, struct pt_regs *regs); -+ -+#ifdef CONFIG_AUDIO -+ -+#define test_tsk_audio(regs) (regs->NDS32_FUCOP_CTL & FUCOP_CTL_mskAUEN) -+ -+struct task_struct; -+ -+static inline void enable_audio(void) -+{ -+ SET_FUCOP_CTL(GET_FUCOP_CTL() | FUCOP_CTL_mskAUEN); -+} -+ -+static inline void disable_audio(void) -+{ -+ SET_FUCOP_CTL(GET_FUCOP_CTL() & ~FUCOP_CTL_mskAUEN); -+} -+ -+static inline void release_audio(struct pt_regs *regs) -+{ -+ regs->NDS32_FUCOP_CTL &= ~FUCOP_CTL_mskAUEN; -+ regs->NDS32_ipsw &= ~PSW_mskAEN; -+} -+ -+static inline void grab_audio(struct pt_regs *regs) -+{ -+ regs->NDS32_FUCOP_CTL |= FUCOP_CTL_mskAUEN; -+ regs->NDS32_ipsw |= PSW_mskAEN; -+} -+#ifdef CONFIG_UNLAZY_AUDIO -+static inline void unlazy_audio(struct task_struct *tsk) -+{ -+ preempt_disable(); -+ if (test_tsk_audio(task_pt_regs(tsk))) -+ save_audio(tsk); -+ preempt_enable(); -+} -+#endif -+static inline void clear_audio(struct pt_regs *regs) -+{ -+ preempt_disable(); -+ if (test_tsk_audio(regs)) { -+ release_audio(regs); -+ } -+ preempt_enable(); -+} -+#endif /* CONFIG_AUDIO */ -+#endif /* __ASSEMBLY__ */ -+ -+#endif /* __ASM_NDS32_AUDIO_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/auxvec.h linux-3.4.113/arch/nds32/include/asm/auxvec.h ---- linux-3.4.113.orig/arch/nds32/include/asm/auxvec.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/auxvec.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,9 @@ -+/* -+ * linux/arch/nds32/include/asm/auxvec.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_AUXVEC_H__ -+#define __NDS32_AUXVEC_H__ -+ -+#endif /*__NDS32_AUXVEC_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/barrier.h linux-3.4.113/arch/nds32/include/asm/barrier.h ---- linux-3.4.113.orig/arch/nds32/include/asm/barrier.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/barrier.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,85 @@ -+/* ============================================================================ -+ * -+ * linux/arch/nds32/include/asm/system.h -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for NDS32 architecture. -+ * -+ * Revision History: -+ * -+ * Nov.26.2007 Initial ported by Tom, Shawn, and Steven, -+ * patched for KGDB and refined code by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#ifndef __ASM_NDS32_BARRIER_H -+#define __ASM_NDS32_BARRIER_H -+ -+#ifdef __KERNEL__ -+ -+/* -+ * This is used to ensure the compiler did actually allocate the register we -+ * asked it for some inline assembly sequences. Apparently we can't trust -+ * the compiler from one version to another so a bit of paranoia won't hurt. -+ * This string is meant to be concatenated with the inline asm string and -+ * will cause compilation to stop on mismatch. -+ * (for details, see gcc PR 15089) -+ */ -+#define __asmeq(x, y) ".ifnc " x "," y " ; .err ; .endif\n\t" -+ -+#ifndef __ASSEMBLY__ -+ -+#include -+#include -+ -+struct thread_info; -+struct task_struct; -+ -+struct pt_regs; -+ -+void die(const char *msg, struct pt_regs *regs, int err) -+ __attribute__((noreturn)); -+ -+void die_if_kernel(const char *str, struct pt_regs *regs, int err); -+ -+#include -+ -+#define UDBG_UNDEFINED (1 << 0) -+#define UDBG_SYSCALL (1 << 1) -+#define UDBG_BADABORT (1 << 2) -+#define UDBG_SEGV (1 << 3) -+#define UDBG_BUS (1 << 4) -+ -+extern unsigned int user_debug; -+ -+#define mb() __asm__ __volatile__ ("" : : : "memory") -+#define rmb() mb() -+#define wmb() mb() -+#define read_barrier_depends() do { } while(0) -+#define set_mb(var, value) do { var = value; mb(); } while (0) -+#define set_wmb(var, value) do { var = value; wmb(); } while (0) -+ -+#ifdef CONFIG_SMP -+#define smp_mb() mb() -+#define smp_rmb() rmb() -+#define smp_wmb() wmb() -+#define smp_read_barrier_depends() read_barrier_depends() -+#else -+#define smp_mb() barrier() -+#define smp_rmb() barrier() -+#define smp_wmb() barrier() -+#define smp_read_barrier_depends() do { } while(0) -+#endif -+ -+#endif /* __ASSEMBLY__ */ -+ -+#endif /* __KERNEL__ */ -+ -+#endif //__ASM_NDS32_SYSTEM_H -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/bitfield.h linux-3.4.113/arch/nds32/include/asm/bitfield.h ---- linux-3.4.113.orig/arch/nds32/include/asm/bitfield.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/bitfield.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,895 @@ -+/* -+ * linux/arch/nds32/include/asm/bitfield.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_BITFIELD_H__ -+#define __NDS32_BITFIELD_H__ -+/****************************************************************************** -+ * cr0: CPU_VER (CPU Version Register) -+ *****************************************************************************/ -+#define CPU_VER_offCFGID 0 /* Minor configuration */ -+#define CPU_VER_offREV 16 /* Revision of the CPU version */ -+#define CPU_VER_offCPUID 24 /* Major CPU versions */ -+ -+#define CPU_VER_mskCFGID ( 0xFFFF << CPU_VER_offCFGID ) -+#define CPU_VER_mskREV ( 0xFF << CPU_VER_offREV ) -+#define CPU_VER_mskCPUID ( 0xFF << CPU_VER_offCPUID ) -+ -+/****************************************************************************** -+ * cr1: ICM_CFG (Instruction Cache/Memory Configuration Register) -+ *****************************************************************************/ -+#define ICM_CFG_offISET 0 /* I-cache sets (# of cache lines) per way */ -+#define ICM_CFG_offIWAY 3 /* I-cache ways */ -+#define ICM_CFG_offISZ 6 /* I-cache line size */ -+#define ICM_CFG_offILCK 9 /* I-cache locking support */ -+#define ICM_CFG_offILMB 10 /* On-chip ILM banks */ -+#define ICM_CFG_offBSAV 13 /* ILM base register alignment version */ -+/* bit 15:31 reserved */ -+ -+#define ICM_CFG_mskISET ( 0x7 << ICM_CFG_offISET ) -+#define ICM_CFG_mskIWAY ( 0x7 << ICM_CFG_offIWAY ) -+#define ICM_CFG_mskISZ ( 0x7 << ICM_CFG_offISZ ) -+#define ICM_CFG_mskILCK ( 0x1 << ICM_CFG_offILCK ) -+#define ICM_CFG_mskILMB ( 0x7 << ICM_CFG_offILMB ) -+#define ICM_CFG_mskBSAV ( 0x3 << ICM_CFG_offBSAV ) -+ -+/****************************************************************************** -+ * cr2: DCM_CFG (Data Cache/Memory Configuration Register) -+ *****************************************************************************/ -+#define DCM_CFG_offDSET 0 /* D-cache sets (# of cache lines) per way */ -+#define DCM_CFG_offDWAY 3 /* D-cache ways */ -+#define DCM_CFG_offDSZ 6 /* D-cache line size */ -+#define DCM_CFG_offDLCK 9 /* D-cache locking support */ -+#define DCM_CFG_offDLMB 10 /* On-chip DLM banks */ -+#define DCM_CFG_offBSAV 13 /* DLM base register alignment version */ -+/* bit 15:31 reserved */ -+ -+#define DCM_CFG_mskDSET ( 0x7 << DCM_CFG_offDSET ) -+#define DCM_CFG_mskDWAY ( 0x7 << DCM_CFG_offDWAY ) -+#define DCM_CFG_mskDSZ ( 0x7 << DCM_CFG_offDSZ ) -+#define DCM_CFG_mskDLCK ( 0x1 << DCM_CFG_offDLCK ) -+#define DCM_CFG_mskDLMB ( 0x7 << DCM_CFG_offDLMB ) -+#define DCM_CFG_mskBSAV ( 0x3 << DCM_CFG_offBSAV ) -+ -+/****************************************************************************** -+ * cr3: MMU_CFG (MMU Configuration Register) -+ *****************************************************************************/ -+#define MMU_CFG_offMMPS 0 /* Memory management protection scheme */ -+#define MMU_CFG_offMMPV 2 /* Memory management protection version number */ -+#define MMU_CFG_offFATB 7 /* Fully-associative or non-fully-associative TLB */ -+ -+#ifdef CONFIG_FULL_ASSOC -+#define MMU_CFG_offFATBSZ 8 /* TLB entries while using full-associative TLB */ -+#else -+#define MMU_CFG_offTBW 8 /* TLB ways(non-associative) TBS */ -+#define MMU_CFG_offTBS 11 /* TLB sets per way(non-associative) TBS */ -+/* bit 14:14 reserved */ -+#endif -+ -+#define MMU_CFG_offEP8MIN4 15 /* 8KB page supported while minimum page is 4KB */ -+#define MMU_CFG_offfEPSZ 16 /* Extra page size supported */ -+#define MMU_CFG_offTLBLCK 24 /* TLB locking support */ -+#define MMU_CFG_offHPTWK 25 /* Hardware Page Table Walker implemented */ -+#define MMU_CFG_offDE 26 /* Default endian */ -+#define MMU_CFG_offNTPT 27 /* Partitions for non-translated attributes */ -+#define MMU_CFG_offIVTB 28 /* Invisible TLB */ -+#define MMU_CFG_offVLPT 29 /* VLPT for fast TLB fill handling implemented */ -+#define MMU_CFG_offNTME 30 /* Non-translated VA to PA mapping */ -+/* bit 31 reserved */ -+ -+#define MMU_CFG_mskMMPS ( 0x3 << MMU_CFG_offMMPS ) -+#define MMU_CFG_mskMMPV ( 0x1F << MMU_CFG_offMMPV ) -+#define MMU_CFG_mskFATB ( 0x1 << MMU_CFG_offFATB ) -+#ifdef CONFIG_FULL_ASSOC -+#define MMU_CFG_mskFATBSZ ( 0x7f << MMU_CFG_offFATBSZ ) -+#else -+#define MMU_CFG_mskTBW ( 0x7 << MMU_CFG_offTBW ) -+#define MMU_CFG_mskTBS ( 0x7 << MMU_CFG_offTBS ) -+#endif -+#define MMU_CFG_mskEP8MIN4 ( 0x1 << MMU_CFG_offEP8MIN4 ) -+#define MMU_CFG_mskfEPSZ ( 0xFF << MMU_CFG_offfEPSZ ) -+#define MMU_CFG_mskTLBLCK ( 0x1 << MMU_CFG_offTLBLCK ) -+#define MMU_CFG_mskHPTWK ( 0x1 << MMU_CFG_offHPTWK ) -+#define MMU_CFG_mskDE ( 0x1 << MMU_CFG_offDE ) -+#define MMU_CFG_mskNTPT ( 0x1 << MMU_CFG_offNTPT ) -+#define MMU_CFG_mskIVTB ( 0x1 << MMU_CFG_offIVTB ) -+#define MMU_CFG_mskVLPT ( 0x1 << MMU_CFG_offVLPT ) -+#define MMU_CFG_mskNTME ( 0x1 << MMU_CFG_offNTME ) -+ -+/****************************************************************************** -+ * cr4: MSC_CFG (Misc Configuration Register) -+ *****************************************************************************/ -+#define MSC_CFG_offEDM 0 -+#define MSC_CFG_offLMDMA 1 -+#define MSC_CFG_offPFM 2 -+#define MSC_CFG_offHSMP 3 -+#define MSC_CFG_offTRACE 4 -+#define MSC_CFG_offDIV 5 -+#define MSC_CFG_offMAC 6 -+#define MSC_CFG_offAUDIO 7 -+#define MSC_CFG_offL2C 9 -+#define MSC_CFG_offRDREG 10 -+#define MSC_CFG_offADR24 11 -+#define MSC_CFG_offINTLC 12 -+#define MSC_CFG_offBASEV 13 -+#define MSC_CFG_offNOD 16 -+/* bit 13:31 reserved */ -+ -+#define MSC_CFG_mskEDM ( 0x1 << MSC_CFG_offEDM ) -+#define MSC_CFG_mskLMDMA ( 0x1 << MSC_CFG_offLMDMA ) -+#define MSC_CFG_mskPFM ( 0x1 << MSC_CFG_offPFM ) -+#define MSC_CFG_mskHSMP ( 0x1 << MSC_CFG_offHSMP ) -+#define MSC_CFG_mskTRACE ( 0x1 << MSC_CFG_offTRACE ) -+#define MSC_CFG_mskDIV ( 0x1 << MSC_CFG_offDIV ) -+#define MSC_CFG_mskMAC ( 0x1 << MSC_CFG_offMAC ) -+#define MSC_CFG_mskAUDIO ( 0x3 << MSC_CFG_offAUDIO ) -+#define MSC_CFG_mskL2C ( 0x1 << MSC_CFG_offL2C ) -+#define MSC_CFG_mskRDREG ( 0x1 << MSC_CFG_offRDREG ) -+#define MSC_CFG_mskADR24 ( 0x1 << MSC_CFG_offADR24 ) -+#define MSC_CFG_mskINTLC ( 0x1 << MSC_CFG_offINTLC ) -+#define MSC_CFG_mskBASEV ( 0x7 << MSC_CFG_offBASEV ) -+#define MSC_CFG_mskNOD ( 0x1 << MSC_CFG_offNOD ) -+ -+/****************************************************************************** -+ * cr5: CORE_CFG (Core Identification Register) -+ *****************************************************************************/ -+#define CORE_ID_offCOREID 0 -+/* bit 4:31 reserved */ -+ -+#define CORE_ID_mskCOREID ( 0xF << CORE_ID_offCOREID ) -+ -+/****************************************************************************** -+ * cr6: FUCOP_EXIST (FPU and Coprocessor Existence Configuration Register) -+ *****************************************************************************/ -+#define FUCOP_EXIST_offCP0EX 0 -+#define FUCOP_EXIST_offCP1EX 1 -+#define FUCOP_EXIST_offCP2EX 2 -+#define FUCOP_EXIST_offCP3EX 3 -+#define FUCOP_EXIST_offCP0ISFPU 31 -+ -+#define FUCOP_EXIST_mskCP0EX ( 0x1 << FUCOP_EXIST_offCP0EX ) -+#define FUCOP_EXIST_mskCP1EX ( 0x1 << FUCOP_EXIST_offCP1EX ) -+#define FUCOP_EXIST_mskCP2EX ( 0x1 << FUCOP_EXIST_offCP2EX ) -+#define FUCOP_EXIST_mskCP3EX ( 0x1 << FUCOP_EXIST_offCP3EX ) -+#define FUCOP_EXIST_mskCP0ISFPU ( 0x1 << FUCOP_EXIST_offCP0ISFPU ) -+ -+/****************************************************************************** -+ * ir0: PSW (Processor Status Word Register) -+ * ir1: IPSW (Interruption PSW Register) -+ * ir2: P_IPSW (Previous IPSW Register) -+ *****************************************************************************/ -+#define PSW_offGIE 0 /* Global Interrupt Enable */ -+#define PSW_offINTL 1 /* Interruption Stack Level */ -+#define PSW_offPOM 3 /* Processor Operation Mode, User/Superuser */ -+#define PSW_offBE 5 /* Endianness for data memory access, 1:MSB, 0:LSB */ -+#define PSW_offIT 6 /* Enable instruction address translation */ -+#define PSW_offDT 7 /* Enable data address translation */ -+#define PSW_offIME 8 /* Instruction Machine Error flag */ -+#define PSW_offDME 9 /* Data Machine Error flag */ -+#define PSW_offDEX 10 /* Debug Exception */ -+#define PSW_offHSS 11 /* Hardware Single Stepping */ -+#define PSW_offDRBE 12 /* Device Register Endian Mode */ -+#define PSW_offAEN 13 /* Audio ISA special feature */ -+#define PSW_offWBNA 14 /* Write Back Non-Allocate */ -+#define PSW_offIFCON 15 /* IFC On */ -+#define PSW_offCPL 16 /* Current Priority Level */ -+/* bit 19:31 reserved */ -+ -+#define PSW_mskGIE ( 0x1 << PSW_offGIE ) -+#define PSW_mskINTL ( 0x3 << PSW_offINTL ) -+#define PSW_mskPOM ( 0x3 << PSW_offPOM ) -+#define PSW_mskBE ( 0x1 << PSW_offBE ) -+#define PSW_mskIT ( 0x1 << PSW_offIT ) -+#define PSW_mskDT ( 0x1 << PSW_offDT ) -+#define PSW_mskIME ( 0x1 << PSW_offIME ) -+#define PSW_mskDME ( 0x1 << PSW_offDME ) -+#define PSW_mskDEX ( 0x1 << PSW_offDEX ) -+#define PSW_mskHSS ( 0x1 << PSW_offHSS ) -+#define PSW_mskDRBE ( 0x1 << PSW_offDRBE ) -+#define PSW_mskAEN ( 0x1 << PSW_offAEN ) -+#define PSW_mskWBNA ( 0x1 << PSW_offWBNA ) -+#define PSW_mskIFCON ( 0x1 << PSW_offIFCON ) -+#define PSW_mskCPL ( 0x7 << PSW_offCPL ) -+ -+#define PSW_SYSTEM ( 1 << PSW_offPOM ) -+#define PSW_INTL_1 ( 1 << PSW_offINTL ) -+#define PSW_CPL_NO ( 0 << PSW_offCPL ) -+#define PSW_CPL_ANY ( 7 << PSW_offCPL ) -+/****************************************************************************** -+ * ir3: IVB (Interruption Vector Base Register) -+ *****************************************************************************/ -+/* bit 0:12 reserved */ -+#define IVB_offNIVIC 1 /* Number of input for IVIC Controller */ -+#define IVB_offIVIC_VER 11 /* IVIC Version */ -+#define IVB_offEVIC 13 /* External Vector Interrupt Controller mode */ -+#define IVB_offESZ 14 /* Size of each vector entry */ -+#define IVB_offIVBASE 16 /* BasePA of interrupt vector table */ -+ -+#define IVB_mskNIVIC ( 0x7 << IVB_offNIVIC ) -+#define IVB_mskIVIC_VER ( 0x3 << IVB_offIVIC_VER ) -+#define IVB_mskEVIC ( 0x1 << IVB_offEVIC ) -+#define IVB_mskESZ ( 0x3 << IVB_offESZ ) -+#define IVB_mskIVBASE ( 0xFFFF << IVB_offIVBASE ) -+ -+/****************************************************************************** -+ * ir4: EVA (Exception Virtual Address Register) -+ * ir5: P_EVA (Previous EVA Register) -+ *****************************************************************************/ -+ -+ /* This register contains the VA that causes the exception */ -+ -+/****************************************************************************** -+ * ir6: ITYPE (Interruption Type Register) -+ * ir7: P_ITYPE (Previous ITYPE Register) -+ *****************************************************************************/ -+#define ITYPE_offETYPE 0 /* Exception Type */ -+#define ITYPE_offINST 4 /* Exception caused by insn fetch or data access */ -+/* bit 5:15 reserved */ -+#define ITYPE_offSWID 16 /* SWID of debugging exception */ -+/* bit 31:31 reserved */ -+ -+#define ITYPE_mskETYPE ( 0xF << ITYPE_offETYPE ) -+#define ITYPE_mskINST ( 0x1 << ITYPE_offINST ) -+#define ITYPE_mskSWID ( 0x7FFF << ITYPE_offSWID ) -+ -+/* Additional definitions for ITYPE register */ -+#define ITYPE_offSTYPE 16 /* Arithmetic Sub Type */ -+#define ITYPE_offCPID 20 /* Co-Processor ID which generate the exception */ -+ -+#define ITYPE_mskSTYPE ( 0xF << ITYPE_offSTYPE ) -+#define ITYPE_mskCPID ( 0x3 << ITYPE_offCPID ) -+ -+/****************************************************************************** -+ * ir8: MERR (Machine Error Log Register) -+ *****************************************************************************/ -+/* bit 0:30 reserved */ -+#define MERR_offBUSERR 31 /* Bus error caused by a load insn */ -+ -+#define MERR_mskBUSERR ( 0x1 << MERR_offBUSERR ) -+ -+/****************************************************************************** -+ * ir9: IPC (Interruption Program Counter Register) -+ * ir10: P_IPC (Previous IPC Register) -+ * ir11: OIPC (Overflow Interruption Program Counter Register) -+ *****************************************************************************/ -+ -+ /* This is the shadow stack register of the Program Counter */ -+ -+/****************************************************************************** -+ * ir12: P_P0 (Previous P0 Register) -+ * ir13: P_P1 (Previous P1 Register) -+ *****************************************************************************/ -+ -+ /* These are shadow registers of $p0 and $p1 */ -+ -+/****************************************************************************** -+ * ir14: INT_MASK (Interruption Masking Register) -+ *****************************************************************************/ -+#define INT_MASK_offH0IM 0 /* Hardware Interrupt 0 Mask bit */ -+#define INT_MASK_offH1IM 1 /* Hardware Interrupt 1 Mask bit */ -+#define INT_MASK_offH2IM 2 /* Hardware Interrupt 2 Mask bit */ -+#define INT_MASK_offH3IM 3 /* Hardware Interrupt 3 Mask bit */ -+#define INT_MASK_offH4IM 4 /* Hardware Interrupt 4 Mask bit */ -+#define INT_MASK_offH5IM 5 /* Hardware Interrupt 5 Mask bit */ -+/* bit 6:15 reserved */ -+#define INT_MASK_offSIM 16 /* Software Interrupt Mask bit */ -+/* bit 17:29 reserved */ -+#define INT_MASK_offIDIVZE 30 /* Enable detection for Divide-By-Zero */ -+#define INT_MASK_offDSSIM 31 /* Default Single Stepping Interruption Mask */ -+ -+#define INT_MASK_mskH0IM ( 0x1 << INT_MASK_offH0IM ) -+#define INT_MASK_mskH1IM ( 0x1 << INT_MASK_offH1IM ) -+#define INT_MASK_mskH2IM ( 0x1 << INT_MASK_offH2IM ) -+#define INT_MASK_mskH3IM ( 0x1 << INT_MASK_offH3IM ) -+#define INT_MASK_mskH4IM ( 0x1 << INT_MASK_offH4IM ) -+#define INT_MASK_mskH5IM ( 0x1 << INT_MASK_offH5IM ) -+#define INT_MASK_mskSIM ( 0x1 << INT_MASK_offSIM ) -+#define INT_MASK_mskIDIVZE ( 0x1 << INT_MASK_offIDIVZE ) -+#define INT_MASK_mskDSSIM ( 0x1 << INT_MASK_offDSSIM ) -+ -+/****************************************************************************** -+ * ir15: INT_PEND (Interrupt Pending Register) -+ *****************************************************************************/ -+#define INT_PEND_offH0I 0 /* Hardware Interrupt 0 pending bit */ -+#define INT_PEND_offH1I 1 /* Hardware Interrupt 1 pending bit */ -+#define INT_PEND_offH2I 2 /* Hardware Interrupt 2 pending bit */ -+#define INT_PEND_offH3I 3 /* Hardware Interrupt 3 pending bit */ -+#define INT_PEND_offH4I 4 /* Hardware Interrupt 4 pending bit */ -+#define INT_PEND_offH5I 5 /* Hardware Interrupt 5 pending bit */ -+ -+#define INT_PEND_offCIPL 0 /* Current Interrupt Priority Level */ -+ -+/* bit 6:15 reserved */ -+#define INT_PEND_offSWI 16 /* Software Interrupt pending bit */ -+/* bit 17:31 reserved */ -+ -+#define INT_PEND_mskH0I ( 0x1 << INT_PEND_offH0I ) -+#define INT_PEND_mskH1I ( 0x1 << INT_PEND_offH1I ) -+#define INT_PEND_mskH2I ( 0x1 << INT_PEND_offH2I ) -+#define INT_PEND_mskH3I ( 0x1 << INT_PEND_offH3I ) -+#define INT_PEND_mskH4I ( 0x1 << INT_PEND_offH4I ) -+#define INT_PEND_mskH5I ( 0x1 << INT_PEND_offH5I ) -+#define INT_PEND_mskCIPL ( 0x1 << INT_PEND_offCIPL ) -+#define INT_PEND_mskSWI ( 0x1 << INT_PEND_offSWI ) -+ -+/****************************************************************************** -+ * mr0: MMU_CTL (MMU Control Register) -+ *****************************************************************************/ -+#define MMU_CTL_offD 0 /* Default minimum page size */ -+#define MMU_CTL_offNTC0 1 /* Non-Translated Cachebility of partition 0 */ -+#define MMU_CTL_offNTC1 3 /* Non-Translated Cachebility of partition 1 */ -+#define MMU_CTL_offNTC2 5 /* Non-Translated Cachebility of partition 2 */ -+#define MMU_CTL_offNTC3 7 /* Non-Translated Cachebility of partition 3 */ -+#define MMU_CTL_offTBALCK 9 /* TLB all-lock resolution scheme */ -+#define MMU_CTL_offMPZIU 10 /* Multiple Page Size In Use bit */ -+#define MMU_CTL_offNTM0 11 /* Non-Translated VA to PA of partition 0 */ -+#define MMU_CTL_offNTM1 13 /* Non-Translated VA to PA of partition 1 */ -+#define MMU_CTL_offNTM2 15 /* Non-Translated VA to PA of partition 2 */ -+#define MMU_CTL_offNTM3 17 /* Non-Translated VA to PA of partition 3 */ -+/* bit 19:31 reserved */ -+ -+#define MMU_CTL_mskD ( 0x1 << MMU_CTL_offD ) -+#define MMU_CTL_mskNTC0 ( 0x3 << MMU_CTL_offNTC0 ) -+#define MMU_CTL_mskNTC1 ( 0x3 << MMU_CTL_offNTC1 ) -+#define MMU_CTL_mskNTC2 ( 0x3 << MMU_CTL_offNTC2 ) -+#define MMU_CTL_mskNTC3 ( 0x3 << MMU_CTL_offNTC3 ) -+#define MMU_CTL_mskTBALCK ( 0x1 << MMU_CTL_offTBALCK ) -+#define MMU_CTL_mskMPZIU ( 0x1 << MMU_CTL_offMPZIU ) -+#define MMU_CTL_mskNTM0 ( 0x3 << MMU_CTL_offNTM0 ) -+#define MMU_CTL_mskNTM1 ( 0x3 << MMU_CTL_offNTM1 ) -+#define MMU_CTL_mskNTM2 ( 0x3 << MMU_CTL_offNTM2 ) -+#define MMU_CTL_mskNTM3 ( 0x3 << MMU_CTL_offNTM3 ) -+ -+/****************************************************************************** -+ * mr1: L1_PPTB (L1 Physical Page Table Base Register) -+ *****************************************************************************/ -+#define L1_PPTB_offNV 0 /* Enable Hardware Page Table Walker (HPTWK) */ -+/* bit 1:11 reserved */ -+#define L1_PPTB_offBASE 12 /* First level physical page table base address */ -+ -+#define L1_PPTB_mskNV ( 0x1 << L1_PPTB_offNV ) -+#define L1_PPTB_mskBASE ( 0xFFFFF << L1_PPTB_offBASE ) -+ -+/****************************************************************************** -+ * mr2: TLB_VPN (TLB Access VPN Register) -+ *****************************************************************************/ -+/* bit 0:11 reserved */ -+#define TLB_VPN_offVPN 12 /* Virtual Page Number */ -+ -+#define TLB_VPN_mskVPN ( 0xFFFFF << TLB_VPN_offVPN ) -+ -+/****************************************************************************** -+ * mr3: TLB_DATA (TLB Access Data Register) -+ *****************************************************************************/ -+#define TLB_DATA_offV 0 /* PTE is valid and present */ -+#define TLB_DATA_offM 1 /* Page read/write access privilege */ -+#define TLB_DATA_offD 4 /* Dirty bit */ -+#define TLB_DATA_offX 5 /* Executable bit */ -+#define TLB_DATA_offA 6 /* Access bit */ -+#define TLB_DATA_offG 7 /* Global page (shared across contexts) */ -+#define TLB_DATA_offC 8 /* Cacheability atribute */ -+/* bit 11:11 reserved */ -+#define TLB_DATA_offPPN 12 /* Phisical Page Number */ -+ -+#define TLB_DATA_mskV ( 0x1 << TLB_DATA_offV ) -+#define TLB_DATA_mskM ( 0x7 << TLB_DATA_offM ) -+#define TLB_DATA_mskD ( 0x1 << TLB_DATA_offD ) -+#define TLB_DATA_mskX ( 0x1 << TLB_DATA_offX ) -+#define TLB_DATA_mskA ( 0x1 << TLB_DATA_offA ) -+#define TLB_DATA_mskG ( 0x1 << TLB_DATA_offG ) -+#define TLB_DATA_mskC ( 0x7 << TLB_DATA_offC ) -+#define TLB_DATA_mskPPN ( 0xFFFFF << TLB_DATA_offPPN ) -+ -+/****************************************************************************** -+ * mr4: TLB_MISC (TLB Access Misc Register) -+ *****************************************************************************/ -+#define TLB_MISC_offACC_PSZ 0 /* Page size of a PTE entry */ -+#define TLB_MISC_offCID 4 /* Context id */ -+/* bit 13:31 reserved */ -+ -+#define TLB_MISC_mskACC_PSZ ( 0xF << TLB_MISC_offACC_PSZ ) -+#define TLB_MISC_mskCID ( 0x1FF << TLB_MISC_offCID ) -+ -+/****************************************************************************** -+ * mr5: VLPT_IDX (Virtual Linear Page Table Index Register) -+ *****************************************************************************/ -+#define VLPT_IDX_offZERO 0 /* Always 0 */ -+#define VLPT_IDX_offEVPN 2 /* Exception Virtual Page Number */ -+#define VLPT_IDX_offVLPTB 22 /* Base VA of VLPT */ -+ -+#define VLPT_IDX_mskZERO ( 0x3 << VLPT_IDX_offZERO ) -+#define VLPT_IDX_mskEVPN ( 0xFFFFF << VLPT_IDX_offEVPN ) -+#define VLPT_IDX_mskVLPTB ( 0x3FF << VLPT_IDX_offVLPTB ) -+ -+/****************************************************************************** -+ * mr6: ILMB (Instruction Local Memory Base Register) -+ *****************************************************************************/ -+#define ILMB_offIEN 0 /* Enable ILM */ -+#define ILMB_offILMSZ 1 /* Size of ILM */ -+/* bit 5:19 reserved */ -+#define ILMB_offIBPA 20 /* Base PA of ILM */ -+ -+#define ILMB_mskIEN ( 0x1 << ILMB_offIEN ) -+#define ILMB_mskILMSZ ( 0xF << ILMB_offILMSZ ) -+#define ILMB_mskIBPA ( 0xFFF << ILMB_offIBPA ) -+ -+/****************************************************************************** -+ * mr7: DLMB (Data Local Memory Base Register) -+ *****************************************************************************/ -+#define DLMB_offDEN 0 /* Enable DLM */ -+#define DLMB_offDLMSZ 1 /* Size of DLM */ -+#define DLMB_offDBM 5 /* Enable Double-Buffer Mode for DLM */ -+#define DLMB_offDBB 6 /* Double-buffer bank which can be accessed by the processor */ -+/* bit 7:19 reserved */ -+#define DLMB_offDBPA 20 /* Base PA of DLM */ -+ -+#define DLMB_mskDEN ( 0x1 << DLMB_offDEN ) -+#define DLMB_mskDLMSZ ( 0xF << DLMB_offDLMSZ ) -+#define DLMB_mskDBM ( 0x1 << DLMB_offDBM ) -+#define DLMB_mskDBB ( 0x1 << DLMB_offDBB ) -+#define DLMB_mskDBPA ( 0xFFF << DLMB_offDBPA ) -+ -+/****************************************************************************** -+ * mr8: CACHE_CTL (Cache Control Register) -+ *****************************************************************************/ -+#define CACHE_CTL_offIC_EN 0 /* Enable I-cache */ -+#define CACHE_CTL_offDC_EN 1 /* Enable D-cache */ -+#define CACHE_CTL_offICALCK 2 /* I-cache all-lock resolution scheme */ -+#define CACHE_CTL_offDCALCK 3 /* D-cache all-lock resolution scheme */ -+#define CACHE_CTL_offDCCWF 4 /* Enable D-cache Critical Word Forwarding */ -+#define CACHE_CTL_offDCPMW 5 /* Enable D-cache concurrent miss and write-back processing */ -+/* bit 6:31 reserved */ -+ -+#define CACHE_CTL_mskIC_EN ( 0x1 << CACHE_CTL_offIC_EN ) -+#define CACHE_CTL_mskDC_EN ( 0x1 << CACHE_CTL_offDC_EN ) -+#define CACHE_CTL_mskICALCK ( 0x1 << CACHE_CTL_offICALCK ) -+#define CACHE_CTL_mskDCALCK ( 0x1 << CACHE_CTL_offDCALCK ) -+#define CACHE_CTL_mskDCCWF ( 0x1 << CACHE_CTL_offDCCWF ) -+#define CACHE_CTL_mskDCPMW ( 0x1 << CACHE_CTL_offDCPMW ) -+ -+/****************************************************************************** -+ * mr9: HSMP_SADDR (High Speed Memory Port Starting Address) -+ *****************************************************************************/ -+#define HSMP_SADDR_offEN 0 /* Enable control bit for the High Speed Memory port */ -+/* bit 1:19 reserved */ -+ -+#define HSMP_SADDR_offRANGE 1 /* Denote the address range (only defined in HSMP v2 ) */ -+#define HSMP_SADDR_offSADDR 20 /* Starting base PA of the High Speed Memory Port region */ -+ -+#define HSMP_SADDR_mskEN ( 0x1 << HSMP_SADDR_offEN ) -+#define HSMP_SADDR_mskRANGE ( 0xFFF << HSMP_SADDR_offRANGE ) -+#define HSMP_SADDR_mskSADDR ( 0xFFF << HSMP_SADDR_offSADDR ) -+ -+/****************************************************************************** -+ * mr10: HSMP_EADDR (High Speed Memory Port Ending Address) -+ *****************************************************************************/ -+/* bit 0:19 reserved */ -+#define HSMP_EADDR_offEADDR 20 -+ -+#define HSMP_EADDR_mskEADDR ( 0xFFF << HSMP_EADDR_offEADDR ) -+ -+/****************************************************************************** -+ * dr0+(n*5): BPCn (n=0-7) (Breakpoint Control Register) -+ *****************************************************************************/ -+#define BPC_offWP 0 /* Configuration of BPAn */ -+#define BPC_offEL 1 /* Enable BPAn */ -+#define BPC_offS 2 /* Data address comparison for a store instruction */ -+#define BPC_offP 3 /* Compared data address is PA */ -+#define BPC_offC 4 /* CID value is compared with the BPCIDn register */ -+#define BPC_offBE0 5 /* Enable byte mask for the comparison with register */ -+#define BPC_offBE1 6 /* Enable byte mask for the comparison with register */ -+#define BPC_offBE2 7 /* Enable byte mask for the comparison with register */ -+#define BPC_offBE3 8 /* Enable byte mask for the comparison with register */ -+#define BPC_offT 9 /* Enable breakpoint Embedded Tracer triggering operation */ -+ -+#define BPC_mskWP ( 0x1 << BPC_offWP ) -+#define BPC_mskEL ( 0x1 << BPC_offEL ) -+#define BPC_mskS ( 0x1 << BPC_offS ) -+#define BPC_mskP ( 0x1 << BPC_offP ) -+#define BPC_mskC ( 0x1 << BPC_offC ) -+#define BPC_mskBE0 ( 0x1 << BPC_offBE0 ) -+#define BPC_mskBE1 ( 0x1 << BPC_offBE1 ) -+#define BPC_mskBE2 ( 0x1 << BPC_offBE2 ) -+#define BPC_mskBE3 ( 0x1 << BPC_offBE3 ) -+#define BPC_mskT ( 0x1 << BPC_offT ) -+ -+/****************************************************************************** -+ * dr1+(n*5): BPAn (n=0-7) (Breakpoint Address Register) -+ *****************************************************************************/ -+ -+ /* These registers contain break point address */ -+ -+/****************************************************************************** -+ * dr2+(n*5): BPAMn (n=0-7) (Breakpoint Address Mask Register) -+ *****************************************************************************/ -+ -+ /* These registerd contain the address comparison mask for the BPAn register */ -+ -+/****************************************************************************** -+ * dr3+(n*5): BPVn (n=0-7) Breakpoint Data Value Register -+ *****************************************************************************/ -+ -+ /* The BPVn register contains the data value that will be compared with the -+ * incoming load/store data value */ -+ -+/****************************************************************************** -+ * dr4+(n*5): BPCIDn (n=0-7) (Breakpoint Context ID Register) -+ *****************************************************************************/ -+#define BPCID_offCID 0 /* CID that will be compared with a process's CID */ -+/* bit 9:31 reserved */ -+ -+#define BPCID_mskCID ( 0x1FF << BPCID_offCID ) -+ -+/****************************************************************************** -+ * dr40: EDM_CFG (EDM Configuration Register) -+ *****************************************************************************/ -+#define EDM_CFG_offBC 0 /* Number of hardware breakpoint sets implemented */ -+#define EDM_CFG_offDIMU 3 /* Debug Instruction Memory Unit exists */ -+/* bit 4:15 reserved */ -+#define EDM_CFG_offVER 16 /* EDM version */ -+ -+#define EDM_CFG_mskBC ( 0x7 << EDM_CFG_offBC ) -+#define EDM_CFG_mskDIMU ( 0x1 << EDM_CFG_offDIMU ) -+#define EDM_CFG_mskVER ( 0xFFFF << EDM_CFG_offVER ) -+ -+/****************************************************************************** -+ * dr41: EDMSW (EDM Status Word) -+ *****************************************************************************/ -+#define EDMSW_offWV 0 /* Write Valid */ -+#define EDMSW_offRV 1 /* Read Valid */ -+#define EDMSW_offDE 2 /* Debug exception has occurred for this core */ -+/* bit 3:31 reserved */ -+ -+#define EDMSW_mskWV ( 0x1 << EDMSW_offWV ) -+#define EDMSW_mskRV ( 0x1 << EDMSW_offRV ) -+#define EDMSW_mskDE ( 0x1 << EDMSW_offDE ) -+ -+/****************************************************************************** -+ * dr42: EDM_CTL (EDM Control Register) -+ *****************************************************************************/ -+/* bit 0:30 reserved */ -+#define EDM_CTL_offV3_EDM_MODE 6 /* EDM compatibility control bit */ -+#define EDM_CTL_offDEH_SEL 31 /* Controls where debug exception is directed to */ -+ -+#define EDM_CTL_mskV3_EDM_MODE ( 0x1 << EDM_CTL_offV3_EDM_MODE ) -+#define EDM_CTL_mskDEH_SEL ( 0x1 << EDM_CTL_offDEH_SEL ) -+ -+/****************************************************************************** -+ * dr43: EDM_DTR (EDM Data Transfer Register) -+ *****************************************************************************/ -+ -+ /* This is used to exchange data between the embedded EDM logic -+ * and the processor core */ -+ -+/****************************************************************************** -+ * dr44: BPMTC (Breakpoint Match Trigger Counter Register) -+ *****************************************************************************/ -+#define BPMTC_offBPMTC 0 /* Breakpoint match trigger counter value */ -+/* bit 16:31 reserved */ -+ -+#define BPMTC_mskBPMTC ( 0xFFFF << BPMTC_offBPMTC ) -+ -+/****************************************************************************** -+ * dr45: DIMBR (Debug Instruction Memory Base Register) -+ *****************************************************************************/ -+/* bit 0:11 reserved */ -+#define DIMBR_offDIMB 12 /* Base address of the Debug Instruction Memory (DIM) */ -+#define DIMBR_mskDIMB ( 0xFFFFF << DIMBR_offDIMB ) -+ -+/****************************************************************************** -+ * dr46: TECR0(Trigger Event Control register 0) -+ * dr47: TECR1 (Trigger Event Control register 1) -+ *****************************************************************************/ -+#define TECR_offBP 0 /* Controld which BP is used as a trigger source */ -+#define TECR_offNMI 8 /* Use NMI as a trigger source */ -+#define TECR_offHWINT 9 /* Corresponding interrupt is used as a trigger source */ -+#define TECR_offEVIC 15 /* Enable HWINT as a trigger source in EVIC mode */ -+#define TECR_offSYS 16 /* Enable SYSCALL instruction as a trigger source */ -+#define TECR_offDBG 17 /* Enable debug exception as a trigger source */ -+#define TECR_offMRE 18 /* Enable MMU related exception as a trigger source */ -+#define TECR_offE 19 /* An exception is used as a trigger source */ -+/* bit 20:30 reserved */ -+#define TECR_offL 31 /* Link/Cascade TECR0 trigger event to TECR1 trigger event */ -+ -+#define TECR_mskBP ( 0xFF << TECR_offBP ) -+#define TECR_mskNMI ( 0x1 << TECR_offBNMI ) -+#define TECR_mskHWINT ( 0x3F << TECR_offBHWINT ) -+#define TECR_mskEVIC ( 0x1 << TECR_offBEVIC ) -+#define TECR_mskSYS ( 0x1 << TECR_offBSYS ) -+#define TECR_mskDBG ( 0x1 << TECR_offBDBG ) -+#define TECR_mskMRE ( 0x1 << TECR_offBMRE ) -+#define TECR_mskE ( 0x1 << TECR_offE ) -+#define TECR_mskL ( 0x1 << TECR_offL ) -+ -+/****************************************************************************** -+ * pfr0-2: PFMC0-2 (Performance Counter Register 0-2) -+ *****************************************************************************/ -+ -+ /* These registers contains performance event count */ -+ -+/****************************************************************************** -+ * pfr3: PFM_CTL (Performance Counter Control Register) -+ *****************************************************************************/ -+#define PFM_CTL_offEN0 0 /* Enable PFMC0 */ -+#define PFM_CTL_offEN1 1 /* Enable PFMC1 */ -+#define PFM_CTL_offEN2 2 /* Enable PFMC2 */ -+#define PFM_CTL_offIE0 3 /* Enable interrupt for PFMC0 */ -+#define PFM_CTL_offIE1 4 /* Enable interrupt for PFMC1 */ -+#define PFM_CTL_offIE2 5 /* Enable interrupt for PFMC2 */ -+#define PFM_CTL_offOVF0 6 /* Overflow bit of PFMC0 */ -+#define PFM_CTL_offOVF1 7 /* Overflow bit of PFMC1 */ -+#define PFM_CTL_offOVF2 8 /* Overflow bit of PFMC2 */ -+#define PFM_CTL_offKS0 9 /* Enable superuser mode event counting for PFMC0 */ -+#define PFM_CTL_offKS1 10 /* Enable superuser mode event counting for PFMC1 */ -+#define PFM_CTL_offKS2 11 /* Enable superuser mode event counting for PFMC2 */ -+#define PFM_CTL_offKU0 12 /* Enable user mode event counting for PFMC0 */ -+#define PFM_CTL_offKU1 13 /* Enable user mode event counting for PFMC1 */ -+#define PFM_CTL_offKU2 14 /* Enable user mode event counting for PFMC2 */ -+#define PFM_CTL_offSEL0 15 /* The event selection for PFMC0 */ -+#define PFM_CTL_offSEL1 21 /* The event selection for PFMC1 */ -+#define PFM_CTL_offSEL2 27 /* The event selection for PFMC2 */ -+/* bit 28:31 reserved */ -+ -+#define PFM_CTL_mskEN0 ( 0x01 << PFM_CTL_offEN0 ) -+#define PFM_CTL_mskEN1 ( 0x01 << PFM_CTL_offEN1 ) -+#define PFM_CTL_mskEN2 ( 0x01 << PFM_CTL_offEN2 ) -+#define PFM_CTL_mskIE0 ( 0x01 << PFM_CTL_offIE0 ) -+#define PFM_CTL_mskIE1 ( 0x01 << PFM_CTL_offIE1 ) -+#define PFM_CTL_mskIE2 ( 0x01 << PFM_CTL_offIE2 ) -+#define PFM_CTL_mskOVF0 ( 0x01 << PFM_CTL_offOVF0 ) -+#define PFM_CTL_mskOVF1 ( 0x01 << PFM_CTL_offOVF1 ) -+#define PFM_CTL_mskOVF2 ( 0x01 << PFM_CTL_offOVF2 ) -+#define PFM_CTL_mskKS0 ( 0x01 << PFM_CTL_offKS0 ) -+#define PFM_CTL_mskKS1 ( 0x01 << PFM_CTL_offKS1 ) -+#define PFM_CTL_mskKS2 ( 0x01 << PFM_CTL_offKS2 ) -+#define PFM_CTL_mskKU0 ( 0x01 << PFM_CTL_offKU0 ) -+#define PFM_CTL_mskKU1 ( 0x01 << PFM_CTL_offKU1 ) -+#define PFM_CTL_mskKU2 ( 0x01 << PFM_CTL_offKU2 ) -+#define PFM_CTL_mskSEL0 ( 0x01 << PFM_CTL_offSEL0 ) -+#define PFM_CTL_mskSEL1 ( 0x3F << PFM_CTL_offSEL1 ) -+#define PFM_CTL_mskSEL2 ( 0x3F << PFM_CTL_offSEL2 ) -+ -+/****************************************************************************** -+ * SDZ_CTL (Structure Downsizing Control Register) -+ *****************************************************************************/ -+#define SDZ_CTL_offICDZ 0 /* I-cache downsizing control */ -+#define SDZ_CTL_offDCDZ 3 /* D-cache downsizing control */ -+#define SDZ_CTL_offMTBDZ 6 /* MTLB downsizing control */ -+#define SDZ_CTL_offBTBDZ 9 /* Branch Target Table downsizing control */ -+/* bit 12:31 reserved */ -+#define SDZ_CTL_mskICDZ ( 0x07 << SDZ_CTL_offICDZ ) -+#define SDZ_CTL_mskDCDZ ( 0x07 << SDZ_CTL_offDCDZ ) -+#define SDZ_CTL_mskMTBDZ ( 0x07 << SDZ_CTL_offMTBDZ ) -+#define SDZ_CTL_mskBTBDZ ( 0x07 << SDZ_CTL_offBTBDZ ) -+ -+/****************************************************************************** -+ * N12MISC_CTL (N12 Miscellaneous Control Register) -+ *****************************************************************************/ -+#define N12MISC_CTL_offBTB 0 /* Disable Branch Target Buffer */ -+#define N12MISC_CTL_offRTP 1 /* Disable Return Target Predictor */ -+#define N12MISC_CTL_offPTEPF 2 /* Disable HPTWK L2 PTE pefetch */ -+/* bit 3:31 reserved */ -+ -+#define N12MISC_CTL_makBTB ( 0x1 << N12MISC_CTL_offBTB ) -+#define N12MISC_CTL_makRTP ( 0x1 << N12MISC_CTL_offRTP ) -+#define N12MISC_CTL_makPTEPF ( 0x1 << N12MISC_CTL_offPTEPF ) -+ -+/****************************************************************************** -+ * PRUSR_ACC_CTL (Privileged Resource User Access Control Registers) -+ *****************************************************************************/ -+#define PRUSR_ACC_CTL_offDMA_EN 0 /* Allow user mode access of DMA registers */ -+#define PRUSR_ACC_CTL_offPFM_EN 1 /* Allow user mode access of PFM registers */ -+ -+#define PRUSR_ACC_CTL_mskDMA_EN ( 0x1 << PRUSR_ACC_CTL_offDMA_EN ) -+#define PRUSR_ACC_CTL_mskPFM_EN ( 0x1 << PRUSR_ACC_CTL_offPFM_EN ) -+ -+/****************************************************************************** -+ * dmar0: DMA_CFG (DMA Configuration Register) -+ *****************************************************************************/ -+#define DMA_CFG_offNCHN 0 /* The number of DMA channels implemented */ -+#define DMA_CFG_offUNEA 2 /* Un-aligned External Address transfer feature */ -+#define DMA_CFG_off2DET 3 /* 2-D Element Transfer feature */ -+/* bit 4:15 reserved */ -+#define DMA_CFG_offVER 16 /* DMA architecture and implementation version */ -+ -+#define DMA_CFG_mskNCHN ( 0x3 << DMA_CFG_offNCHN ) -+#define DMA_CFG_mskUNEA ( 0x1 << DMA_CFG_offUNEA ) -+#define DMA_CFG_msk2DET ( 0x1 << DMA_CFG_off2DET ) -+#define DMA_CFG_mskVER ( 0xFFFF << DMA_CFG_offVER ) -+ -+/****************************************************************************** -+ * dmar1: DMA_GCSW (DMA Global Control and Status Word Register) -+ *****************************************************************************/ -+#define DMA_GCSW_offC0STAT 0 /* DMA channel 0 state */ -+#define DMA_GCSW_offC1STAT 3 /* DMA channel 1 state */ -+/* bit 6:11 reserved */ -+#define DMA_GCSW_offC0INT 12 /* DMA channel 0 generate interrupt */ -+#define DMA_GCSW_offC1INT 13 /* DMA channel 1 generate interrupt */ -+/* bit 14:30 reserved */ -+#define DMA_GCSW_offEN 31 /* Enable DMA engine */ -+ -+#define DMA_GCSW_mskC0STAT ( 0x7 << DMA_GCSW_offC0STAT ) -+#define DMA_GCSW_mskC1STAT ( 0x7 << DMA_GCSW_offC1STAT ) -+#define DMA_GCSW_mskC0INT ( 0x1 << DMA_GCSW_offC0INT ) -+#define DMA_GCSW_mskC1INT ( 0x1 << DMA_GCSW_offC1INT ) -+#define DMA_GCSW_mskEN ( 0x1 << DMA_GCSW_offEN ) -+ -+/****************************************************************************** -+ * dmar2: DMA_CHNSEL (DMA Channel Selection Register) -+ *****************************************************************************/ -+#define DMA_CHNSEL_offCHAN 0 /* Selected channel number */ -+/* bit 2:31 reserved */ -+ -+#define DMA_CHNSEL_mskCHAN ( 0x3 << DMA_CHNSEL_offCHAN ) -+ -+/****************************************************************************** -+ * dmar3: DMA_ACT (DMA Action Register) -+ *****************************************************************************/ -+#define DMA_ACT_offACMD 0 /* DMA Action Command */ -+/* bit 2:31 reserved */ -+#define DMA_ACT_mskACMD ( 0x3 << DMA_ACT_offACMD ) -+ -+/****************************************************************************** -+ * dmar4: DMA_SETUP (DMA Setup Register) -+ *****************************************************************************/ -+#define DMA_SETUP_offLM 0 /* Local Memory Selection */ -+#define DMA_SETUP_offTDIR 1 /* Transfer Direction */ -+#define DMA_SETUP_offTES 2 /* Transfer Element Size */ -+#define DMA_SETUP_offESTR 4 /* External memory transfer Stride */ -+#define DMA_SETUP_offCIE 16 /* Interrupt Enable on Completion */ -+#define DMA_SETUP_offSIE 17 /* Interrupt Enable on explicit Stop */ -+#define DMA_SETUP_offEIE 18 /* Interrupt Enable on Error */ -+#define DMA_SETUP_offUE 19 /* Enable the Un-aligned External Address */ -+#define DMA_SETUP_off2DE 20 /* Enable the 2-D External Transfer */ -+#define DMA_SETUP_offCOA 21 /* Transfer Coalescable */ -+/* bit 22:31 reserved */ -+ -+#define DMA_SETUP_mskLM ( 0x1 << DMA_SETUP_offLM ) -+#define DMA_SETUP_mskTDIR ( 0x1 << DMA_SETUP_offTDIR ) -+#define DMA_SETUP_mskTES ( 0x3 << DMA_SETUP_offTES ) -+#define DMA_SETUP_mskESTR ( 0xFFF << DMA_SETUP_offESTR ) -+#define DMA_SETUP_mskCIE ( 0x1 << DMA_SETUP_offCIE ) -+#define DMA_SETUP_mskSIE ( 0x1 << DMA_SETUP_offSIE ) -+#define DMA_SETUP_mskEIE ( 0x1 << DMA_SETUP_offEIE ) -+#define DMA_SETUP_mskUE ( 0x1 << DMA_SETUP_offUE ) -+#define DMA_SETUP_msk2DE ( 0x1 << DMA_SETUP_off2DE ) -+#define DMA_SETUP_mskCOA ( 0x1 << DMA_SETUP_offCOA ) -+ -+/****************************************************************************** -+ * dmar5: DMA_ISADDR (DMA Internal Start Address Register) -+ *****************************************************************************/ -+#define DMA_ISADDR_offISADDR 0 /* Internal Start Address */ -+/* bit 20:31 reserved */ -+#define DMA_ISADDR_mskISADDR ( 0xFFFFF << DMA_ISADDR_offISADDR ) -+ -+/****************************************************************************** -+ * dmar6: DMA_ESADDR (DMA External Start Address Register) -+ *****************************************************************************/ -+/* This register holds External Start Address */ -+ -+/****************************************************************************** -+ * dmar7: DMA_TCNT (DMA Transfer Element Count Register) -+ *****************************************************************************/ -+#define DMA_TCNT_offTCNT 0 /* DMA transfer element count */ -+/* bit 18:31 reserved */ -+#define DMA_TCNT_mskTCNT ( 0x3FFFF << DMA_TCNT_offTCNT ) -+ -+/****************************************************************************** -+ * dmar8: DMA_STATUS (DMA Status Register) -+ *****************************************************************************/ -+#define DMA_STATUS_offSTAT 0 /* DMA channel state */ -+#define DMA_STATUS_offSTUNA 3 /* Un-aligned error on External Stride value */ -+#define DMA_STATUS_offDERR 4 /* DMA Transfer Disruption Error */ -+#define DMA_STATUS_offEUNA 5 /* Un-aligned error on the External address */ -+#define DMA_STATUS_offIUNA 6 /* Un-aligned error on the Internal address */ -+#define DMA_STATUS_offIOOR 7 /* Out-Of-Range error on the Internal address */ -+#define DMA_STATUS_offEBUS 8 /* Bus Error on an External DMA transfer */ -+#define DMA_STATUS_offESUP 9 /* DMA setup error */ -+/* bit 10:31 reserved */ -+ -+#define DMA_STATUS_mskSTAT ( 0x7 << DMA_STATUS_offSTAT ) -+#define DMA_STATUS_mskSTUNA ( 0x1 << DMDMA_STATUS_offSTUNA ) -+#define DMA_STATUS_mskDERR ( 0x1 << DMDMA_STATUS_offDERR ) -+#define DMA_STATUS_mskEUNA ( 0x1 << DMDMA_STATUS_offEUNA ) -+#define DMA_STATUS_mskIUNA ( 0x1 << DMDMA_STATUS_offIUNA ) -+#define DMA_STATUS_mskIOOR ( 0x1 << DMDMA_STATUS_offIOOR ) -+#define DMA_STATUS_mskEBUS ( 0x1 << DMDMA_STATUS_offEBUS ) -+#define DMA_STATUS_mskESUP ( 0x1 << DMDMA_STATUS_offESUP ) -+ -+/****************************************************************************** -+ * dmar9: DMA_2DSET (DMA 2D Setup Register) -+ *****************************************************************************/ -+#define DMA_2DSET_offWECNT 0 /* The Width Element Count for a 2-D region */ -+#define DMA_2DSET_offHTSTR 16 /* The Height Stride for a 2-D region */ -+ -+#define DMA_2DSET_mskHTSTR ( 0xFFFF << DMA_2DSET_offHTSTR ) -+#define DMA_2DSET_mskWECNT ( 0xFFFF << DMA_2DSET_offWECNT ) -+ -+/****************************************************************************** -+ * dmar10: DMA_2DSCTL (DMA 2D Startup Control Register) -+ *****************************************************************************/ -+#define DMA_2DSCTL_offSTWECNT 0 /* Startup Width Element Count for a 2-D region */ -+/* bit 16:31 reserved */ -+ -+#define DMA_2DSCTL_mskSTWECNT ( 0xFFFF << DMA_2DSCTL_offSTWECNT ) -+ -+/****************************************************************************** -+ * fpcsr: FPCSR (Floating-Point Control Status Register) -+ *****************************************************************************/ -+#define FPCSR_offRM 0 -+#define FPCSR_offIVO 2 -+#define FPCSR_offDBZ 3 -+#define FPCSR_offOVF 4 -+#define FPCSR_offUDF 5 -+#define FPCSR_offIEX 6 -+#define FPCSR_offIVOE 7 -+#define FPCSR_offDBZE 8 -+#define FPCSR_offOVFE 9 -+#define FPCSR_offUDFE 10 -+#define FPCSR_offIEXE 11 -+#define FPCSR_offDNZ 12 -+#define FPCSR_offIVOT 13 -+#define FPCSR_offDBZT 14 -+#define FPCSR_offOVFT 15 -+#define FPCSR_offUDFT 16 -+#define FPCSR_offIEXT 17 -+#define FPCSR_offDNIT 18 -+#define FPCSR_offRIT 19 -+ -+#define FPCSR_mskRM ( 0x3 << FPCSR_offRM ) -+#define FPCSR_mskIVO ( 0x1 << FPCSR_offIVO ) -+#define FPCSR_mskDBZ ( 0x1 << FPCSR_offDBZ ) -+#define FPCSR_mskOVF ( 0x1 << FPCSR_offOVF ) -+#define FPCSR_mskUDF ( 0x1 << FPCSR_offUDF ) -+#define FPCSR_mskIEX ( 0x1 << FPCSR_offIEX ) -+#define FPCSR_mskIVOE ( 0x1 << FPCSR_offIVOE ) -+#define FPCSR_mskDBZE ( 0x1 << FPCSR_offDBZE ) -+#define FPCSR_mskOVFE ( 0x1 << FPCSR_offOVFE ) -+#define FPCSR_mskUDFE ( 0x1 << FPCSR_offUDFE ) -+#define FPCSR_mskIEXE ( 0x1 << FPCSR_offIEXE ) -+#define FPCSR_mskDNZ ( 0x1 << FPCSR_offDNZ ) -+#define FPCSR_mskIVOT ( 0x1 << FPCSR_offIVOT ) -+#define FPCSR_mskDBZT ( 0x1 << FPCSR_offDBZT ) -+#define FPCSR_mskOVFT ( 0x1 << FPCSR_offOVFT ) -+#define FPCSR_mskUDFT ( 0x1 << FPCSR_offUDFT ) -+#define FPCSR_mskIEXT ( 0x1 << FPCSR_offIEXT ) -+#define FPCSR_mskDNIT ( 0x1 << FPCSR_offDNIT ) -+#define FPCSR_mskRIT ( 0x1 << FPCSR_offRIT ) -+#define FPCSR_mskALL (FPCSR_mskIVO | FPCSR_mskDBZ | FPCSR_mskOVF | FPCSR_mskUDF | FPCSR_mskIEX) -+#define FPCSR_mskALLE (FPCSR_mskIVOE | FPCSR_mskDBZE | FPCSR_mskOVFE | FPCSR_mskUDFE | FPCSR_mskIEXE) -+#define FPCSR_mskALLT (FPCSR_mskIVOT | FPCSR_mskDBZT | FPCSR_mskOVFT | FPCSR_mskUDFT | FPCSR_mskIEXT |FPCSR_mskDNIT | FPCSR_mskRIT) -+ -+/****************************************************************************** -+ * fpcfg: FPCFG (Floating-Point Configuration Register) -+ *****************************************************************************/ -+#define FPCFG_offSP 0 -+#define FPCFG_offDP 1 -+#define FPCFG_offFREG 2 -+#define FPCFG_offFMA 4 -+#define FPCFG_offIMVER 22 -+#define FPCFG_offAVER 27 -+ -+#define FPCFG_mskSP ( 0x1 << FPCFG_offSP ) -+#define FPCFG_mskDP ( 0x1 << FPCFG_offDP ) -+#define FPCFG_mskFREG ( 0x3 << FPCFG_offFREG ) -+#define FPCFG_mskFMA ( 0x1 << FPCFG_offFMA ) -+#define FPCFG_mskIMVER ( 0x1F << FPCFG_offIMVER ) -+#define FPCFG_mskAVER ( 0x1F << FPCFG_offAVER ) -+ -+/****************************************************************************** -+ * fucpr: FUCOP_CTL (FPU and Coprocessor Enable Control Register) -+ *****************************************************************************/ -+#define FUCOP_CTL_offCP0EN 0 -+#define FUCOP_CTL_offCP1EN 1 -+#define FUCOP_CTL_offCP2EN 2 -+#define FUCOP_CTL_offCP3EN 3 -+#define FUCOP_CTL_offAUEN 31 -+ -+#define FUCOP_CTL_mskCP0EN ( 0x1 << FUCOP_CTL_offCP0EN ) -+#define FUCOP_CTL_mskCP1EN ( 0x1 << FUCOP_CTL_offCP1EN ) -+#define FUCOP_CTL_mskCP2EN ( 0x1 << FUCOP_CTL_offCP2EN ) -+#define FUCOP_CTL_mskCP3EN ( 0x1 << FUCOP_CTL_offCP3EN ) -+#define FUCOP_CTL_mskAUEN ( 0x1 << FUCOP_CTL_offAUEN ) -+ -+#endif /* __NDS32_BITFIELD_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/bitops.h linux-3.4.113/arch/nds32/include/asm/bitops.h ---- linux-3.4.113.orig/arch/nds32/include/asm/bitops.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/bitops.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,256 @@ -+/* -+ * linux/arch/nds32/include/asm/bitops.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_BITOPS_H__ -+#define __NDS32_BITOPS_H__ -+ -+#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) -+ -+/* -+#include -+ -+static inline void ____atomic_set_bit(unsigned int bit, volatile unsigned long *p) -+{ -+ unsigned long flags; -+ unsigned long mask = 1UL << (bit & 31); -+ -+ p += bit >> 5; -+ -+ raw_local_irq_save(flags); -+ *p |= mask; -+ raw_local_irq_restore(flags); -+} -+ -+static inline void ____atomic_clear_bit(unsigned int bit, volatile unsigned long *p) -+{ -+ unsigned long flags; -+ unsigned long mask = 1UL << (bit & 31); -+ -+ p += bit >> 5; -+ -+ raw_local_irq_save(flags); -+ *p &= ~mask; -+ raw_local_irq_restore(flags); -+} -+ -+static inline void ____atomic_change_bit(unsigned int bit, volatile unsigned long *p) -+{ -+ unsigned long flags; -+ unsigned long mask = 1UL << (bit & 31); -+ -+ p += bit >> 5; -+ -+ raw_local_irq_save(flags); -+ *p ^= mask; -+ raw_local_irq_restore(flags); -+} -+ -+static inline int -+____atomic_test_and_set_bit(unsigned int bit, volatile unsigned long *p) -+{ -+ unsigned long flags; -+ unsigned int res; -+ unsigned long mask = 1UL << (bit & 31); -+ -+ p += bit >> 5; -+ -+ raw_local_irq_save(flags); -+ res = *p; -+ *p = res | mask; -+ raw_local_irq_restore(flags); -+ -+ return (res & mask) != 0; -+} -+static inline int -+____atomic_test_and_clear_bit(unsigned int bit, volatile unsigned long *p) -+{ -+ unsigned long flags; -+ unsigned int res; -+ unsigned long mask = 1UL << (bit & 31); -+ -+ p += bit >> 5; -+ -+ raw_local_irq_save(flags); -+ res = *p; -+ *p = res & ~mask; -+ raw_local_irq_restore(flags); -+ -+ return (res & mask) != 0; -+} -+ -+static inline int -+____atomic_test_and_change_bit(unsigned int bit, volatile unsigned long *p) -+{ -+ unsigned long flags; -+ unsigned int res; -+ unsigned long mask = 1UL << (bit & 31); -+ -+ p += bit >> 5; -+ -+ raw_local_irq_save(flags); -+ res = *p; -+ *p = res ^ mask; -+ raw_local_irq_restore(flags); -+ -+ return (res & mask) != 0; -+} -+ -+#include -+#ifndef CONFIG_SMP -+#define ATOMIC_BITOP(name,nr,p) \ -+ (__builtin_constant_p(nr) ? ____atomic_##name(nr, p) : _##name(nr,p)) -+#else -+#define ATOMIC_BITOP(name,nr,p) _##name(nr,p) -+#endif -+ -+#define set_bit(nr,p) ATOMIC_BITOP(set_bit,nr,p) -+*/ -+ -+static inline void set_bit(int nr,volatile unsigned long *addr) -+{ -+ unsigned long mask = BIT_MASK(nr); -+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); -+ unsigned long tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tor\t%0, %0, %2\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (p), "r" (mask) -+ : "memory"); -+} -+ -+static inline void clear_bit(int nr, volatile unsigned long *addr) -+{ -+ unsigned long mask = BIT_MASK(nr); -+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); -+ unsigned long tmp; -+ -+ mask = ~mask; -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tand\t%0, %0, %2\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (p), "r" (mask) -+ : "memory"); -+} -+ -+static inline void change_bit(int nr, volatile unsigned long *addr) -+{ -+ unsigned long mask = BIT_MASK(nr); -+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); -+ unsigned long tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\txor\t%0, %0, %2\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (p), "r" (mask) -+ : "memory"); -+} -+ -+static inline int test_and_set_bit(int nr, volatile unsigned long *addr) -+{ -+ unsigned long mask = BIT_MASK(nr); -+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); -+ unsigned long tmp ,ret; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%2+$r15]\n" -+ "\tor\t%1, %0, %3\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (ret), "=&r" (tmp) -+ : "r" (p), "r" (mask) -+ : "memory"); -+ return (ret & mask) != 0; -+} -+ -+static inline int test_and_clear_bit(int nr, volatile unsigned long *addr) -+{ -+ unsigned long mask = BIT_MASK(nr); -+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); -+ unsigned long tmp, ret; -+ unsigned long mask2 = ~mask; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%2+$r15]\n" -+ "\tand\t%1, %0, %3\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (ret), "=&r" (tmp) -+ : "r" (p), "r" (mask2) -+ : "memory"); -+ return (ret & mask) != 0; -+} -+ -+static inline int test_and_change_bit(int nr, volatile unsigned long *addr) -+{ -+ unsigned long mask = BIT_MASK(nr); -+ unsigned long *p = ((unsigned long *)addr) + BIT_WORD(nr); -+ unsigned long tmp, ret; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%2+$r15]\n" -+ "\txor\t%1, %0, %3\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (ret), "=&r" (tmp) -+ : "r" (p), "r" (mask) -+ : "memory"); -+ return (ret & mask) != 0; -+} -+#else -+#include -+#include -+#endif -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+ -+#include -+ -+/* -+ * Ext2 is defined to use little-endian byte ordering. -+ */ -+#include -+ -+#endif /* __KERNEL__ */ -+ -+#define smp_mb__before_clear_bit() barrier() -+#define smp_mb__after_clear_bit() barrier() -+ -+#endif /* __NDS32_BITOPS_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/bitsperlong.h linux-3.4.113/arch/nds32/include/asm/bitsperlong.h ---- linux-3.4.113.orig/arch/nds32/include/asm/bitsperlong.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/bitsperlong.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1 @@ -+#include -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/bug.h linux-3.4.113/arch/nds32/include/asm/bug.h ---- linux-3.4.113.orig/arch/nds32/include/asm/bug.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/bug.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,18 @@ -+/* -+ * linux/arch/nds32/include/asm/bug.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_BUG_H__ -+#define __NDS32_BUG_H__ -+ -+#define HAVE_ARCH_BUG -+#include -+ -+#define BUG() do { \ -+ dump_stack(); \ -+ printk("BUG: failure at %s:%d/%s()!\n", __FILE__, __LINE__, __FUNCTION__); \ -+ panic("BUG!"); \ -+} while (0) -+ -+#endif /* __NDS32_BUG_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/bugs.h linux-3.4.113/arch/nds32/include/asm/bugs.h ---- linux-3.4.113.orig/arch/nds32/include/asm/bugs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/bugs.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/bugs.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_BUGS_H__ -+#define __NDS32_BUGS_H__ -+ -+static inline void check_bugs(void) {} -+ -+#endif /* __NDS32_BUGS_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/byteorder.h linux-3.4.113/arch/nds32/include/asm/byteorder.h ---- linux-3.4.113.orig/arch/nds32/include/asm/byteorder.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/byteorder.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,15 @@ -+/* -+ * linux/arch/nds32/include/asm/byteorder.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_BYTEORDER_H__ -+#define __NDS32_BYTEORDER_H__ -+ -+#ifdef __NDS32_EB__ -+#include -+#else -+#include -+#endif -+ -+#endif /* __NDS32_BYTEORDER_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cacheflush.h linux-3.4.113/arch/nds32/include/asm/cacheflush.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cacheflush.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cacheflush.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,55 @@ -+/* -+ * linux/arch/nds32/include/asm/cacheflush.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_CACHEFLUSH_H__ -+#define __NDS32_CACHEFLUSH_H__ -+ -+#include -+ -+#define PG_dcache_dirty PG_arch_1 -+ -+void flush_cache_mm(struct mm_struct *mm); -+ -+void flush_cache_dup_mm(struct mm_struct *mm); -+ -+void flush_cache_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end); -+ -+void flush_cache_page(struct vm_area_struct *vma, -+ unsigned long addr, unsigned long pfn); -+ -+void flush_cache_kmaps(void); -+ -+void flush_cache_vmap(unsigned long start, unsigned long end); -+ -+void flush_cache_vunmap(unsigned long start, unsigned long end); -+ -+ -+void flush_dcache_page(struct page *page); -+ -+void copy_to_user_page(struct vm_area_struct *vma, struct page *page, -+ unsigned long vaddr, void *dst, void *src, int len); -+ -+void copy_from_user_page(struct vm_area_struct *vma, struct page *page, -+ unsigned long vaddr, void *dst, void *src, int len); -+ -+#ifndef CONFIG_CPU_CACHE_NONALIASING -+#define ARCH_HAS_FLUSH_ANON_PAGE -+void flush_anon_page(struct vm_area_struct *vma, -+ struct page *page, unsigned long vaddr); -+ -+#define ARCH_HAS_FLUSH_KERNEL_DCACHE_PAGE -+void flush_kernel_dcache_page(struct page *page); -+#endif -+ -+void flush_icache_range(unsigned long start, unsigned long end); -+ -+void flush_icache_page(struct vm_area_struct *vma, struct page *page); -+ -+#define flush_dcache_mmap_lock(mapping) spin_lock_irq(&(mapping)->tree_lock) -+#define flush_dcache_mmap_unlock(mapping) spin_unlock_irq(&(mapping)->tree_lock) -+ -+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 1 -+#endif /* __NDS32_CACHEFLUSH_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cache.h linux-3.4.113/arch/nds32/include/asm/cache.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cache.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cache.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,22 @@ -+/* -+ * linux/arch/nds32/include/asm/cache.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_CACHE_H__ -+#define __NDS32_CACHE_H__ -+ -+#define L1_CACHE_BYTES 32 -+#define L1_CACHE_SHIFT 5 -+ -+/* -+ * * Memory returned by kmalloc() may be used for DMA, so we must make -+ * * sure that all such allocations are cache aligned. Otherwise, -+ * * unrelated code may cause parts of the buffer to be read into the -+ * * cache before the transfer is done, causing old data to be seen by -+ * * the CPU. -+ * */ -+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES -+ -+ -+#endif /* __NDS32_CACHE_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cache_info.h linux-3.4.113/arch/nds32/include/asm/cache_info.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cache_info.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cache_info.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,17 @@ -+/* -+ * linux/arch/nds32/include/asm/cache.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+struct cache_info { -+ unsigned char cache_type; -+ unsigned char ways; -+ unsigned char way_bits; -+ unsigned char line_bits; -+ unsigned char line_size; -+ unsigned char set_bits; -+ unsigned short sets; -+ unsigned short size; -+ unsigned short aliasing_num; -+ unsigned int aliasing_mask; -+ unsigned int not_aliasing_mask; -+}; -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/checksum.h linux-3.4.113/arch/nds32/include/asm/checksum.h ---- linux-3.4.113.orig/arch/nds32/include/asm/checksum.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/checksum.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,173 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 1995, 96, 97, 98, 99, 2001 by Ralf Baechle -+ * Copyright (C) 1999 Silicon Graphics, Inc. -+ * Copyright (C) 2001 Thiemo Seufer. -+ * Copyright (C) 2002 Maciej W. Rozycki -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+#ifndef _ASM_CHECKSUM_H -+#define _ASM_CHECKSUM_H -+ -+#include -+ -+#include -+ -+/* -+ * computes the checksum of a memory block at buff, length len, -+ * and adds in "sum" (32-bit) -+ * -+ * returns a 32-bit number suitable for feeding into itself -+ * or csum_tcpudp_magic -+ * -+ * this function must be called with even lengths, except -+ * for the last fragment, which may be odd -+ * -+ * it's best to have buff aligned on a 32-bit boundary -+ */ -+unsigned int csum_partial(const void *buff, int len, unsigned int sum); -+ -+/* -+ * this is a new version of the above that records errors it finds in *errp, -+ * but continues and zeros the rest of the buffer. -+ */ -+unsigned int csum_partial_copy_from_user(const unsigned char *src, unsigned char *dst, int len, -+ unsigned int sum, int *errp); -+ -+/* -+ * Copy and checksum to user -+ */ -+#define HAVE_CSUM_COPY_USER -+static inline unsigned int csum_and_copy_to_user (const unsigned char *src, -+ unsigned char __user *dst, -+ int len, int sum, -+ int *err_ptr) -+{ -+ sum = csum_partial(src, len, sum); -+ -+ if (copy_to_user(dst, src, len)) { -+ *err_ptr = -EFAULT; -+ return -1; -+ } -+ -+ return sum; -+} -+ -+/* -+ * the same as csum_partial, but copies from user space (but on MIPS -+ * we have just one address space, so this is identical to the above) -+ */ -+unsigned int csum_partial_copy_nocheck(const unsigned char *src, unsigned char *dst, -+ int len, unsigned int sum); -+ -+/* -+ * Fold a partial checksum without adding pseudo headers -+ */ -+static inline unsigned short int csum_fold(unsigned int sum) -+{ -+ __asm__( -+ "slli\t$p1,%0,16\n\t" -+ "add\t%0,%0,$p1\n\t" -+ "slt\t$p1,%0,$p1\n\t" -+ "srli\t%0,%0,16\n\t" -+ "add\t%0,%0,$p1\n\t" -+ "movi\t$p1,0xffff\n\t" -+ "xor\t%0,%0,$p1" -+ : "=r" (sum) -+ : "0" (sum)); -+ -+ return sum; -+} -+ -+/* -+ * This is a version of ip_compute_csum() optimized for IP headers, -+ * which always checksum on 4 octet boundaries. -+ * -+ * By Jorge Cwik , adapted for linux by -+ * Arnt Gulbrandsen. -+ */ -+static inline unsigned short ip_fast_csum(unsigned char *iph, unsigned int ihl) -+{ -+ unsigned int *word = (unsigned int *) iph; -+ unsigned int *stop = word + ihl; -+ unsigned int csum; -+ int carry; -+ -+ csum = word[0]; -+ csum += word[1]; -+ carry = (csum < word[1]); -+ csum += carry; -+ -+ csum += word[2]; -+ carry = (csum < word[2]); -+ csum += carry; -+ -+ csum += word[3]; -+ carry = (csum < word[3]); -+ csum += carry; -+ -+ word += 4; -+ do { -+ csum += *word; -+ carry = (csum < *word); -+ csum += carry; -+ word++; -+ } while (word != stop); -+ -+ return csum_fold(csum); -+} -+ -+static inline unsigned int csum_tcpudp_nofold(unsigned long saddr, -+ unsigned long daddr, unsigned short len, unsigned short proto, -+ unsigned int sum) -+{ -+ __asm__( -+ "add\t%0, %0, %2\n\t" -+ "slt\t$p1, %0, %2\n\t" -+ "add\t%0, %0, $p1\n\t" -+ -+ "add\t%0, %0, %3\n\t" -+ "slt\t$p1, %0, %3\n\t" -+ "add\t%0, %0, $p1\n\t" -+ -+ "add\t%0, %0, %4\n\t" -+ "slt\t$p1, %0, %4\n\t" -+ "add\t%0, %0, $p1" -+ : "=r" (sum) -+ : "0" (daddr), "r"(saddr), -+#ifdef __NDS32_EL__ -+ "r" (((unsigned long)htons(len)<<16) + proto*256), -+#else -+ "r" (((unsigned long)(proto)<<16) + len), -+#endif -+ "r" ((__force unsigned long)sum)); -+ -+ return sum; -+} -+ -+/* -+ * computes the checksum of the TCP/UDP pseudo-header -+ * returns a 16-bit checksum, already complemented -+ */ -+static inline unsigned short int csum_tcpudp_magic(unsigned long saddr, -+ unsigned long daddr, -+ unsigned short len, -+ unsigned short proto, -+ unsigned int sum) -+{ -+ return csum_fold(csum_tcpudp_nofold(saddr, daddr, len, proto, sum)); -+} -+ -+/* -+ * this routine is used for miscellaneous IP-like checksums, mainly -+ * in icmp.c -+ */ -+static inline unsigned short ip_compute_csum(const void * buff, int len) -+{ -+ return csum_fold(csum_partial(buff, len, 0)); -+} -+ -+#endif /* _ASM_CHECKSUM_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cmpxchg.h linux-3.4.113/arch/nds32/include/asm/cmpxchg.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cmpxchg.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cmpxchg.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,88 @@ -+#ifndef __ASM_NDS32_CMPXCHG_H -+#define __ASM_NDS32_CMPXCHG_H -+ -+#include -+ -+#define xchg(ptr,x) \ -+ ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) -+ -+static inline unsigned long __xchg(unsigned long x, volatile void *ptr, int size) -+{ -+ extern void __bad_xchg(volatile void *, int); -+ unsigned long ret; -+ unsigned long flags; -+ -+ switch (size) { -+ case 4: -+#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%2+$r15]\n" -+ "\tori\t%1, %3, #0x0\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (ret), "=&r" (flags) -+ : "r" (ptr), "r" (x) -+ : "memory"); -+#else -+ raw_local_irq_save(flags); -+ ret = *(volatile unsigned long *)ptr; -+ *(volatile unsigned long *)ptr = x; -+ raw_local_irq_restore(flags); -+#endif -+ break; -+ default: -+ __bad_xchg(ptr, size); -+ ret = 0; -+ } -+ return ret; -+} -+ -+ -+#define __HAVE_ARCH_CMPXCHG 1 -+ -+static inline unsigned long __cmpxchg(volatile void * ptr, unsigned long old, -+ unsigned long new, int size) -+{ -+ extern void __cmpxchg_called_with_bad_pointer(void); /*nonexistence */ -+ unsigned long retval, tmp; -+ unsigned long flags; -+ switch (size) { -+ case 4: -+#if defined(CONFIG_SMP) || !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%3+$r15]\n" -+ "\tsub\t%2, %0, %5\n" -+ "\tcmovz\t%1, %4, %2\n" -+ "\tcmovn\t%1, %0, %2\n" -+ "\tscw\t%1, [%3+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (retval), "=&r" (flags), "=&r" (tmp) -+ : "r" (ptr), "r" (new), "r" (old)); -+#else -+ raw_local_irq_save(flags); -+ retval = *(volatile unsigned long *)ptr; -+ if (retval == old) -+ *(volatile unsigned long *)ptr = new; -+ raw_local_irq_restore(flags); -+#endif -+ break; -+ default: -+ __cmpxchg_called_with_bad_pointer(); -+ tmp = 0; -+ } -+ return retval; -+} -+ -+#define cmpxchg(ptr,o,n) \ -+ ({ \ -+ __typeof__(*(ptr)) _o_ = (o); \ -+ __typeof__(*(ptr)) _n_ = (n); \ -+ (__typeof__(*(ptr))) __cmpxchg((ptr), (unsigned long)_o_, \ -+ (unsigned long)_n_, sizeof(*(ptr))); \ -+ }) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cpu.h linux-3.4.113/arch/nds32/include/asm/cpu.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cpu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cpu.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * linux/arch/nds32/include/asm/cpu.h -+ * -+ * Copyright (C) 2004-2005 ARM Ltd. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_NDS32_CPU_H -+#define __ASM_NDS32_CPU_H -+ -+#include -+ -+struct cpuinfo_nds32 { -+ struct cpu cpu; -+#ifdef CONFIG_SMP -+ unsigned int loops_per_jiffy; -+#endif -+}; -+ -+DECLARE_PER_CPU(struct cpuinfo_nds32, cpu_data); -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cputime.h linux-3.4.113/arch/nds32/include/asm/cputime.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cputime.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cputime.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/cputime.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_CPUTIME_H__ -+#define __NDS32_CPUTIME_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/cpuver.h linux-3.4.113/arch/nds32/include/asm/cpuver.h ---- linux-3.4.113.orig/arch/nds32/include/asm/cpuver.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/cpuver.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,34 @@ -+/* -+ * linux/arch/nds32/include/asm/cpuver.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_CPUVER_H__ -+#define __NDS32_CPUVER_H__ -+ -+#include -+#include -+ -+#define GET_CPU_ID()\ -+ (( GET_CPU_VER() & CPU_VER_mskCPUID) >> CPU_VER_offCPUID) -+ -+#define GET_CPU_REV()\ -+ (( GET_CPU_VER() & CPU_VER_mskREV) >> CPU_VER_offREV) -+ -+#define GET_CPU_CFGID()\ -+ (( GET_CPU_VER() & CPU_VER_mskCFGID) >> CPU_VER_offCFGID) -+ -+#define CPU_IS_N1213_43U1HA0()\ -+ (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0c000000) &&\ -+ ((GET_CPU_VER() & CPU_VER_mskREV) == 0x00010000)) -+ -+#define CPU_IS_N1213_43U1HB0()\ -+ (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0c000000) &&\ -+ ((GET_CPU_VER() & CPU_VER_mskREV) == 0x00020000)) -+ -+#define CPU_IS_N1033_S()\ -+ (((GET_CPU_VER() & CPU_VER_mskCPUID) == 0x0a000000) &&\ -+ ((GET_CPU_VER() & CPU_VER_mskREV) == 0x000c0000)) -+ -+#endif -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/current.h linux-3.4.113/arch/nds32/include/asm/current.h ---- linux-3.4.113.orig/arch/nds32/include/asm/current.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/current.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,18 @@ -+/* -+ * linux/arch/nds32/include/asm/current.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_CURRENT_H__ -+#define __NDS32_CURRENT_H__ -+ -+#include -+ -+static inline struct task_struct *get_current(void) -+{ -+ return current_thread_info()->task; -+} -+ -+#define current get_current() -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/delay.h linux-3.4.113/arch/nds32/include/asm/delay.h ---- linux-3.4.113.orig/arch/nds32/include/asm/delay.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/delay.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,39 @@ -+/* -+ * linux/arch/nds32/include/asm/delay.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_DELAY_H__ -+#define __NDS32_DELAY_H__ -+ -+#include -+ -+static inline void __delay(unsigned long loops) -+{ -+ __asm__ __volatile__ ( -+ "1:\n" -+ "\taddi\t%0, %0, -1\n" -+ "\tbgtz\t%0, 1b\n" -+ : "=r" (loops) : "0" (loops)); -+} -+ -+static inline void __udelay(unsigned long usecs, unsigned long lpj) -+{ -+ usecs *= (unsigned long) (((0x8000000000000000ULL / (500000 / HZ)) + -+ 0x80000000ULL) >> 32); -+ usecs=(unsigned long)(((unsigned long long)usecs*lpj)>>32); -+ __delay(usecs); -+} -+ -+#define udelay(usecs) __udelay((usecs), loops_per_jiffy) -+ -+/* make sure "usecs *= ..." in udelay do not overflow. */ -+#if HZ >= 1000 -+#define MAX_UDELAY_MS 1 -+#elif HZ <= 200 -+#define MAX_UDELAY_MS 5 -+#else -+#define MAX_UDELAY_MS (1000 / HZ) -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/device.h linux-3.4.113/arch/nds32/include/asm/device.h ---- linux-3.4.113.orig/arch/nds32/include/asm/device.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/device.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/device.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_DEVICE_H__ -+#define __NDS32_DEVICE_H__ -+ -+#include -+ -+#endif /* __NDS32_DEVICE_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/div64.h linux-3.4.113/arch/nds32/include/asm/div64.h ---- linux-3.4.113.orig/arch/nds32/include/asm/div64.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/div64.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/div64.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_DIV64_H__ -+#define __NDS32_DIV64_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/dmad.h linux-3.4.113/arch/nds32/include/asm/dmad.h ---- linux-3.4.113.orig/arch/nds32/include/asm/dmad.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/dmad.h 2016-12-01 20:59:24.332611980 +0100 -@@ -0,0 +1,1071 @@ -+/* -+ * Copyright Andes Technology Corporation 2007-2008 -+ * All Rights Reserved. -+ * -+ * Revision History: -+ * -+ * Aug.21.2007 Created. -+ * -+ * DESCRIPTION -+ * -+ * DMA controller driver internal supplement library. -+ * -+ */ -+ -+#ifndef __NDS_DMAD_INC__ -+#define __NDS_DMAD_INC__ -+ -+#include -+ -+/***************************************************************************** -+ * Configuration section -+*****************************************************************************/ -+ -+/* Debug trace enable switch */ -+#define DMAD_ERROR_TRACE 1 /* message for fatal errors */ -+//MOD by river 2010.10.19 -+#define DMAD_DEBUG_TRACE 0 /* message for debug trace */ -+//End MOD by river 2010.10.19 -+ -+//#ifndef addr_t -+typedef u32 addr_t; -+//#endif -+/* for amerald */ -+#define AMERALD_PRODUCT_ID 0x41471000 -+#define AMERALD_MASK 0xFFFFF000 -+ -+/***************************************************************************** -+ * DMAC - AG101 AHB -+*****************************************************************************/ -+/* Device base address */ -+#define DMAC_BASE DMAC_FTDMAC020_0_VA_BASE -+ -+/* DMA controller registers (8-bit width) */ -+#define DMAC_INT (DMAC_BASE + 0x00) -+#define DMAC_INT_TC (DMAC_BASE + 0x04) -+#define DMAC_INT_TC_CLR (DMAC_BASE + 0x08) -+#define DMAC_INT_ERRABT (DMAC_BASE + 0x0c) -+#define DMAC_INT_ERRABT_CLR (DMAC_BASE + 0x10) -+#define DMAC_TC (DMAC_BASE + 0x14) -+#define DMAC_ERRABT (DMAC_BASE + 0x18) -+#define DMAC_CH_EN (DMAC_BASE + 0x1c) -+#define DMAC_CH_BUSY (DMAC_BASE + 0x20) -+#define DMAC_CSR (DMAC_BASE + 0x24) -+#define DMAC_SYNC (DMAC_BASE + 0x28) -+ -+/* DMA channel registers base address */ -+#define DMAC_C0_OFFSET 0x100 -+#define DMAC_C1_OFFSET 0x120 -+#define DMAC_C2_OFFSET 0x140 -+#define DMAC_C3_OFFSET 0x160 -+#define DMAC_C4_OFFSET 0x180 -+#define DMAC_C5_OFFSET 0x1a0 -+#define DMAC_C6_OFFSET 0x1c0 -+#define DMAC_C7_OFFSET 0x1e0 -+ -+#define DMAC_C0_BASE (DMAC_BASE + DMAC_C0_OFFSET) -+#define DMAC_C1_BASE (DMAC_BASE + DMAC_C1_OFFSET) -+#define DMAC_C2_BASE (DMAC_BASE + DMAC_C2_OFFSET) -+#define DMAC_C3_BASE (DMAC_BASE + DMAC_C3_OFFSET) -+#define DMAC_C4_BASE (DMAC_BASE + DMAC_C4_OFFSET) -+#define DMAC_C5_BASE (DMAC_BASE + DMAC_C5_OFFSET) -+#define DMAC_C6_BASE (DMAC_BASE + DMAC_C6_OFFSET) -+#define DMAC_C7_BASE (DMAC_BASE + DMAC_C7_OFFSET) -+ -+#define DMAC_MAX_CHANNELS 8 -+#define DMAC_BASE_CH(n) (DMAC_C0_BASE + \ -+ (DMAC_C1_OFFSET - DMAC_C0_OFFSET) * \ -+ (addr_t)(n)) /* n = 0 ~ 3 */ -+ -+#define DMAC_CSR_OFFSET 0x00 -+#define DMAC_CFG_OFFSET 0x04 -+#define DMAC_SRC_ADDR_OFFSET 0x08 -+#define DMAC_DST_ADDR_OFFSET 0x0c -+#define DMAC_LLP_OFFSET 0x10 -+#define DMAC_SIZE_OFFSET 0x14 -+ -+/* DMA channel 0 registers (32-bit width) */ -+#define DMAC_C0_CSR (DMAC_C0_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C0_CFG (DMAC_C0_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C0_SRC_ADDR (DMAC_C0_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C0_DST_ADDR (DMAC_C0_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C0_LLP (DMAC_C0_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C0_SIZE (DMAC_C0_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 1 registers (32-bit width) */ -+#define DMAC_C1_CSR (DMAC_C1_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C1_CFG (DMAC_C1_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C1_SRC_ADDR (DMAC_C1_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C1_DST_ADDR (DMAC_C1_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C1_LLP (DMAC_C1_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C1_SIZE (DMAC_C1_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 2 registers (32-bit width) */ -+#define DMAC_C2_CSR (DMAC_C2_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C2_CFG (DMAC_C2_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C2_SRC_ADDR (DMAC_C2_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C2_DST_ADDR (DMAC_C2_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C2_LLP (DMAC_C2_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C2_SIZE (DMAC_C2_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 3 registers (32-bit width) */ -+#define DMAC_C3_CSR (DMAC_C3_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C3_CFG (DMAC_C3_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C3_SRC_ADDR (DMAC_C3_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C3_DST_ADDR (DMAC_C3_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C3_LLP (DMAC_C3_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C3_SIZE (DMAC_C3_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 4 registers (32-bit width) */ -+#define DMAC_C4_CSR (DMAC_C4_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C4_CFG (DMAC_C4_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C4_SRC_ADDR (DMAC_C4_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C4_DST_ADDR (DMAC_C4_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C4_LLP (DMAC_C4_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C4_SIZE (DMAC_C4_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 5 registers (32-bit width) */ -+#define DMAC_C5_CSR (DMAC_C5_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C5_CFG (DMAC_C5_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C5_SRC_ADDR (DMAC_C5_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C5_DST_ADDR (DMAC_C5_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C5_LLP (DMAC_C5_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C5_SIZE (DMAC_C5_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 6 registers (32-bit width) */ -+#define DMAC_C6_CSR (DMAC_C6_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C6_CFG (DMAC_C6_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C6_SRC_ADDR (DMAC_C6_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C6_DST_ADDR (DMAC_C6_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C6_LLP (DMAC_C6_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C6_SIZE (DMAC_C6_BASE + DMAC_SIZE_OFFSET) -+ -+/* DMA channel 7 registers (32-bit width) */ -+#define DMAC_C7_CSR (DMAC_C7_BASE + DMAC_CSR_OFFSET) -+#define DMAC_C7_CFG (DMAC_C7_BASE + DMAC_CFG_OFFSET) -+#define DMAC_C7_SRC_ADDR (DMAC_C7_BASE + DMAC_SRC_ADDR_OFFSET) -+#define DMAC_C7_DST_ADDR (DMAC_C7_BASE + DMAC_DST_ADDR_OFFSET) -+#define DMAC_C7_LLP (DMAC_C7_BASE + DMAC_LLP_OFFSET) -+#define DMAC_C7_SIZE (DMAC_C7_BASE + DMAC_SIZE_OFFSET) -+ -+/***************************************************************************** -+ * DMAC defs - AG101 AHB -+*****************************************************************************/ -+ -+/* Interrupt status register (+00) */ -+#define DMAC_INT0_MASK 0x01 -+#define DMAC_INT0_BIT 0 -+#define DMAC_INT1_MASK 0x02 -+#define DMAC_INT1_BIT 1 -+#define DMAC_INT2_MASK 0x04 -+#define DMAC_INT2_BIT 2 -+#define DMAC_INT3_MASK 0x08 -+#define DMAC_INT3_BIT 3 -+ -+/* Interrupt for terminal count status register (+0x04) */ -+#define DMAC_INT_TC0_MASK 0x01 -+#define DMAC_INT_TC0_BIT 0 -+#define DMAC_INT_TC1_MASK 0x02 -+#define DMAC_INT_TC1_BIT 1 -+#define DMAC_INT_TC2_MASK 0x04 -+#define DMAC_INT_TC2_BIT 2 -+#define DMAC_INT_TC3_MASK 0x08 -+#define DMAC_INT_TC3_BIT 3 -+#define DMAC_INT_TC4_MASK 0x01 -+#define DMAC_INT_TC4_BIT 0 -+#define DMAC_INT_TC5_MASK 0x02 -+#define DMAC_INT_TC5_BIT 1 -+#define DMAC_INT_TC6_MASK 0x04 -+#define DMAC_INT_TC6_BIT 2 -+#define DMAC_INT_TC7_MASK 0x08 -+#define DMAC_INT_TC7_BIT 3 -+ -+#define DMAC_INT_TC_MASK 0xff -+#define DMAC_INT_TC_SHIFT 0 -+ -+/* Interrupt for terminal count clear register (+0x08) */ -+#define DMAC_INT_TC0_CLR_MASK 0x01 -+#define DMAC_INT_TC0_CLR_BIT 0 -+#define DMAC_INT_TC1_CLR_MASK 0x02 -+#define DMAC_INT_TC1_CLR_BIT 1 -+#define DMAC_INT_TC2_CLR_MASK 0x04 -+#define DMAC_INT_TC2_CLR_BIT 2 -+#define DMAC_INT_TC3_CLR_MASK 0x08 -+#define DMAC_INT_TC3_CLR_BIT 3 -+ -+#define DMAC_INT_TC_CLR_MASK 0x0f -+#define DMAC_INT_TC_CLR_SHIFT 0 -+ -+/* Interrupt for error/abort status register (+0x0c, 32-bits width) */ -+#define DMAC_INT_ERR0_MASK 0x00000001 -+#define DMAC_INT_ERR0_BIT 0 -+#define DMAC_INT_ERR1_MASK 0x00000002 -+#define DMAC_INT_ERR1_BIT 1 -+#define DMAC_INT_ERR2_MASK 0x00000004 -+#define DMAC_INT_ERR2_BIT 2 -+#define DMAC_INT_ERR3_MASK 0x00000008 -+#define DMAC_INT_ERR3_BIT 3 -+ -+#define DMAC_INT_ERR_MASK 0x0000000f -+#define DMAC_INT_ERR_SHIFT 0 -+ -+#define DMAC_INT_ABT0_MASK 0x00010000 -+#define DMAC_INT_ABT0_BIT 16 -+#define DMAC_INT_ABT1_MASK 0x00020000 -+#define DMAC_INT_ABT1_BIT 17 -+#define DMAC_INT_ABT2_MASK 0x00040000 -+#define DMAC_INT_ABT2_BIT 18 -+#define DMAC_INT_ABT3_MASK 0x00080000 -+#define DMAC_INT_ABT3_BIT 19 -+ -+#define DMAC_INT_ABT_MASK 0x000f0000 -+#define DMAC_INT_ABT_SHIFT 16 -+ -+/* Interrupt for error/abort status clear register (+0x10, 32-bits width) */ -+#define DMAC_INT_ERR0_CLR_MASK 0x00000001 -+#define DMAC_INT_ERR0_CLR_BIT 0 -+#define DMAC_INT_ERR1_CLR_MASK 0x00000002 -+#define DMAC_INT_ERR1_CLR_BIT 1 -+#define DMAC_INT_ERR2_CLR_MASK 0x00000004 -+#define DMAC_INT_ERR2_CLR_BIT 2 -+#define DMAC_INT_ERR3_CLR_MASK 0x00000008 -+#define DMAC_INT_ERR3_CLR_BIT 3 -+ -+#define DMAC_INT_ERR_CLR_MASK 0x0000000f -+#define DMAC_INT_ERR_CLR_SHIFT 0 -+ -+#define DMAC_INT_ABT0_CLR_MASK 0x00010000 -+#define DMAC_INT_ABT0_CLR_BIT 16 -+#define DMAC_INT_ABT1_CLR_MASK 0x00020000 -+#define DMAC_INT_ABT1_CLR_BIT 17 -+#define DMAC_INT_ABT2_CLR_MASK 0x00040000 -+#define DMAC_INT_ABT2_CLR_BIT 18 -+#define DMAC_INT_ABT3_CLR_MASK 0x00080000 -+#define DMAC_INT_ABT3_CLR_BIT 19 -+ -+#define DMAC_INT_ABT_CLR_MASK 0x000f0000 -+#define DMAC_INT_ABT_CLR_SHIFT 16 -+ -+/* Terminal count status register (+0x14) */ -+#define DMAC_TC0_MASK 0x01 -+#define DMAC_TC0_BIT 0 -+#define DMAC_TC1_MASK 0x02 -+#define DMAC_TC1_BIT 1 -+#define DMAC_TC2_MASK 0x04 -+#define DMAC_TC2_BIT 2 -+#define DMAC_TC3_MASK 0x08 -+#define DMAC_TC3_BIT 3 -+ -+/* Error/abort status register (+0x18, 32-bits width) */ -+#define DMAC_ERR0_MASK 0x00000001 -+#define DMAC_ERR0_BIT 0 -+#define DMAC_ERR1_MASK 0x00000002 -+#define DMAC_ERR1_BIT 1 -+#define DMAC_ERR2_MASK 0x00000004 -+#define DMAC_ERR2_BIT 2 -+#define DMAC_ERR3_MASK 0x00000008 -+#define DMAC_ERR3_BIT 3 -+ -+#define DMAC_ABT0_MASK 0x00010000 -+#define DMAC_ABT0_BIT 16 -+#define DMAC_ABT1_MASK 0x00020000 -+#define DMAC_ABT1_BIT 17 -+#define DMAC_ABT2_MASK 0x00040000 -+#define DMAC_ABT2_BIT 18 -+#define DMAC_ABT3_MASK 0x00080000 -+#define DMAC_ABT3_BIT 19 -+ -+/* Channel enable status register (+0x1c) */ -+#define DMAC_CH0_EN_MASK 0x01 -+#define DMAC_CH0_EN_BIT 0 -+#define DMAC_CH1_EN_MASK 0x02 -+#define DMAC_CH1_EN_BIT 1 -+#define DMAC_CH2_EN_MASK 0x04 -+#define DMAC_CH2_EN_BIT 2 -+#define DMAC_CH3_EN_MASK 0x08 -+#define DMAC_CH3_EN_BIT 3 -+ -+/* Channel busy status register (+0x20) */ -+#define DMAC_CH0_BUSY_MASK 0x01 -+#define DMAC_CH0_BUSY_BIT 0 -+#define DMAC_CH1_BUSY_MASK 0x02 -+#define DMAC_CH1_BUSY_BIT 1 -+#define DMAC_CH2_BUSY_MASK 0x04 -+#define DMAC_CH2_BUSY_BIT 2 -+#define DMAC_CH3_BUSY_MASK 0x08 -+#define DMAC_CH3_BUSY_BIT 3 -+ -+/* Main configuration status register (+0x24) */ -+#define DMAC_DMACEN_MASK 0x01 -+#define DMAC_DMACEN_BIT 0 -+#define DMAC_M0ENDIAN_MASK 0x02 -+#define DMAC_M0ENDIAN_BIT 1 -+#define DMAC_M1ENDIAN_MASK 0x04 -+#define DMAC_M1ENDIAN_BIT 2 -+ -+ #define DMAC_ENDIAN_LITTLE 0 -+ #define DMAC_ENDIAN_BIG 1 -+ -+/* Sync register (+0x28) */ -+#define DMAC_SYNC0_MASK 0x01 -+#define DMAC_SYNC0_BIT 0 -+#define DMAC_SYNC1_MASK 0x02 -+#define DMAC_SYNC1_BIT 1 -+#define DMAC_SYNC2_MASK 0x04 -+#define DMAC_SYNC2_BIT 2 -+#define DMAC_SYNC3_MASK 0x08 -+#define DMAC_SYNC3_BIT 3 -+ -+/* DMA channel 0~n Control Registers (CH[n]_BASE + 0x00) */ -+#define DMAC_CSR_CH_EN_MASK 0x00000001 -+#define DMAC_CSR_CH_EN_BIT 0 -+ -+#define DMAC_CSR_DST_SEL_MASK 0x00000002 -+#define DMAC_CSR_DST_SEL_BIT 1 -+#define DMAC_CSR_SRC_SEL_MASK 0x00000004 -+#define DMAC_CSR_SRC_SEL_BIT 2 -+ #define DMAC_CSR_SEL_MASTER0 0x00 -+ #define DMAC_CSR_SEL_MASTER1 0x01 -+ -+#define DMAC_CSR_DSTAD_CTL_MASK 0x00000018 -+#define DMAC_CSR_DSTAD_CTL_SHIFT 3 -+#define DMAC_CSR_SRCAD_CTL_MASK 0x00000060 -+#define DMAC_CSR_SRCAD_CTL_SHIFT 5 -+ #define DMAC_CSR_AD_INC 0x00 -+ #define DMAC_CSR_AD_DEC 0x01 -+ #define DMAC_CSR_AD_FIX 0x02 -+ -+#define DMAC_CSR_MODE_MASK 0x00000080 -+#define DMAC_CSR_MODE_BIT 7 -+ #define DMAC_CSR_MODE_NORMAL 0x00 -+ #define DMAC_CSR_MODE_HSHK 0x01 -+ -+#define DMAC_CSR_DST_WIDTH_MASK 0x00000700 -+#define DMAC_CSR_DST_WIDTH_SHIFT 8 -+#define DMAC_CSR_SRC_WIDTH_MASK 0x00003800 -+#define DMAC_CSR_SRC_WIDTH_SHIFT 11 -+ #define DMAC_CSR_WIDTH_8 0x00 -+ #define DMAC_CSR_WIDTH_16 0x01 -+ #define DMAC_CSR_WIDTH_32 0x02 -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+#define DMAC_CYCLE_TO_BYTES(cycle, width) ((cycle) << (width)) -+#define DMAC_BYTES_TO_CYCLE(bytes, width) ((bytes) >> (width)) -+#else -+#define DMAC_CYCLE_TO_BYTES(cycle, width) 0 -+#define DMAC_BYTES_TO_CYCLE(bytes, width) 0 -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+#define DMAC_CSR_ABT 0x00008000 -+#define DMAC_CSR_ABT_BIT 15 -+ -+#define DMAC_CSR_SRC_SIZE_MASK 0x00070000 -+#define DMAC_CSR_SRC_SIZE_SHIFT 16 -+ #define DMAC_CSR_SIZE_1 0x00 -+ #define DMAC_CSR_SIZE_4 0x01 -+ #define DMAC_CSR_SIZE_8 0x02 -+ #define DMAC_CSR_SIZE_16 0x03 -+ #define DMAC_CSR_SIZE_32 0x04 -+ #define DMAC_CSR_SIZE_64 0x05 -+ #define DMAC_CSR_SIZE_128 0x06 -+ #define DMAC_CSR_SIZE_256 0x07 -+ -+#define DMAC_CSR_PROT1 0x00080000 -+#define DMAC_CSR_PROT1_BIT 19 -+#define DMAC_CSR_PROT2 0x00100000 -+#define DMAC_CSR_PROT2_BIT 20 -+#define DMAC_CSR_PROT3 0x00200000 -+#define DMAC_CSR_PROT3_BIT 21 -+ -+#define DMAC_CSR_CHPRI_MASK 0x00c00000 -+#define DMAC_CSR_CHPRI_SHIFT 22 -+ #define DMAC_CSR_CHPRI_0 0x00 -+ #define DMAC_CSR_CHPRI_1 0x01 -+ #define DMAC_CSR_CHPRI_2 0x02 -+ #define DMAC_CSR_CHPRI_3 0x03 -+ -+#define DMAC_CSR_FF_TH_MASK 0x07000000 -+#define DMAC_CSR_FF_TH_SHIFT 24 -+ #define DMAC_CSR_FF_TH_1 0x00 -+ #define DMAC_CSR_FF_TH_2 0x01 -+ #define DMAC_CSR_FF_TH_4 0x02 -+ #define DMAC_CSR_FF_TH_8 0x03 -+ #define DMAC_CSR_FF_TH_16 0x04 -+ -+#define DMAC_CSR_TC_MSK_MSK 0x80000000 -+#define DMAC_CSR_TC_MSK_BIT 31 -+ -+/* DMA channel 0~n Configuration Registers (CH[n]_BASE + 0x04) */ -+#define DMAC_CFG_INT_TC_MSK 0x00000001 -+#define DMAC_CFG_INT_TC_MSK_BIT 0 -+#define DMAC_CFG_INT_ERR_MSK 0x00000002 -+#define DMAC_CFG_INT_ERR_MSK_BIT 1 -+#define DMAC_CFG_INT_ABT_MSK 0x00000004 -+#define DMAC_CFG_INT_ABT_MSK_BIT 2 -+ -+#define DMAC_CFG_INT_SRC_RS_MASK 0x00000078 -+#define DMAC_CFG_INT_SRC_RS_SHIFT 3 -+#define DMAC_CFG_INT_SRC_HE_MASK 0x00000080 -+#define DMAC_CFG_INT_SRC_HE_BIT 7 -+ -+#define DMAC_CFG_BUSY_MASK 0x00000100 -+#define DMAC_CFG_BUSY_BIT 8 -+ -+#define DMAC_CFG_INT_DST_RS_MASK 0x00001e00 -+#define DMAC_CFG_INT_DST_RS_SHIFT 9 -+#define DMAC_CFG_INT_DST_HE_MASK 0x00002000 -+#define DMAC_CFG_INT_DST_HE_BIT 13 -+ -+#ifdef CONFIG_PLAT_AG102 -+ #define DMAC_REQN_IDERX 0 -+ #define DMAC_REQN_IDETX 1 -+ #define DMAC_REQN_I2SAC97RX 2 -+ #define DMAC_REQN_I2SAC97TX 3 -+ #define DMAC_REQN_UART2RX 4 -+ #define DMAC_REQN_UART2TX 5 -+ #define DMAC_REQN_UART1RX 6 -+ #define DMAC_REQN_UART1TX 7 -+ #define DMAC_REQN_SDC 8 -+ #define DMAC_REQN_CFC 9 -+ #define DMAC_REQN_LPCREQ0 10 -+ #define DMAC_REQN_LPCREQ1 11 -+ #define DMAC_REQN_LPCREQ2 12 -+ #define DMAC_REQN_LPCREQ3 13 -+ #define DMAC_REQN_NONE 14 -+ #define DMAC_REQN_LPCREQ5 15 -+ #define DMAC_REQN_MAX 15 -+#else -+ #define DMAC_REQN_NONE PMU_REQN_NONE -+ #define DMAC_REQN_CFC PMU_REQN_CFC -+ #define DMAC_REQN_SSP PMU_REQN_SSP -+ #define DMAC_REQN_UART1TX PMU_REQN_UART1TX -+ #define DMAC_REQN_UART1RX PMU_REQN_UART1RX -+ #define DMAC_REQN_UART2TX PMU_REQN_UART2TX -+ #define DMAC_REQN_UART2RX PMU_REQN_UART2RX -+ #define DMAC_REQN_SDC PMU_REQN_SDC -+ #define DMAC_REQN_I2SAC97TX PMU_REQN_I2SAC97TX -+ #define DMAC_REQN_I2SAC97RX PMU_REQN_I2SAC97RX -+/* for amerald ac97 ssp2 */ -+ #define DMAC_REQN_I2SAC97TX_AMERALD PMU_REQN_I2SAC97TX_AMERALD -+ #define DMAC_REQN_I2SAC97RX_AMERALD PMU_REQN_I2SAC97RX_AMERALD -+ #define DMAC_REQN_USB PMU_REQN_USB -+ #define DMAC_REQN_EXT0 PMU_REQN_EXT0 -+ #define DMAC_REQN_EXT1 PMU_REQN_EXT1 -+ #define DMAC_REQN_MAX PMU_REQN_MAX -+#endif -+#define DMAC_CFG_INT_LLPCNT_MASK 0x000f0000 -+#define DMAC_CFG_INT_LLPCNT_SHIFT 16 -+ -+/* DMA channel 0~n Linked List Descriptor Registers (CH[n]_BASE + 0x10) */ -+#define DMAC_LLP_ADDR_MASK 0xfffffffc -+#define DMAC_LLP_ADDR_SHIFT 2 -+#define DMAC_LLP_MASTER_MASK 0x00000001 -+#define DMAC_LLP_MASTER_BIT 0 -+ #define DMAC_LLP_MASTER_0 0 -+ #define DMAC_LLP_MASTER_1 1 -+ -+/* DMA channel 0~3 Transfer Size Registers (CH[n]_BASE + 0x14) */ -+#define DMAC_TOT_SIZE_MASK 0x003fffff -+#define DMAC_TOT_SIZE_SHIFT 0 -+ -+ -+/***************************************************************************** -+ * APBBR - AG101 AHB to APB Bridge -+*****************************************************************************/ -+/* Device base address */ -+#ifdef CONFIG_PLAT_AG102 -+#define APBBR_BASE APBBR_VA_BASE -+#else -+#define APBBR_BASE APBBRG_FTAPBBRG020S_0_VA_BASE -+#endif -+ -+/* DMA channel A registers (32-bit width) */ -+#define APBBR_DMAA_BASE (APBBR_BASE + 0x80) -+#define APBBR_DMAB_BASE (APBBR_BASE + 0x90) -+#define APBBR_DMAC_BASE (APBBR_BASE + 0xa0) -+#define APBBR_DMAD_BASE (APBBR_BASE + 0xb0) -+ -+#define APBBR_DMA_MAX_CHANNELS APBBRG_FTAPBBRG020S_IRQ_COUNT -+/* n = 0 ~ APBBRG_FTAPBBRG020S_IRQ_COUNT */ -+#define APBBR_DMA_BASE_CH(n) (APBBR_DMAA_BASE + \ -+ (APBBR_DMAB_BASE - APBBR_DMAA_BASE) * \ -+ (addr_t)(n)) -+ -+#define APBBR_DMA_SAD_OFFSET 0x00 -+#define APBBR_DMA_DAD_OFFSET 0x04 -+#define APBBR_DMA_CYC_OFFSET 0x08 -+#define APBBR_DMA_CMD_OFFSET 0x0c -+ -+ -+/***************************************************************************** -+ * APBBR defs - AG101 AHB to APB Bridge -+*****************************************************************************/ -+ -+/* APBBR slave#n (n = 1~6, 8, 11, 16~23) base/size register */ -+#define APBBR_SLAVE_SIZE_MASK 0x000f0000 /* Size of address space */ -+#define APBBR_SLAVE_SIZE_SHIFT 16 -+ #define APBBR_SIZE_1M 0 -+ #define APBBR_SIZE_2M 1 -+ #define APBBR_SIZE_4M 2 -+ #define APBBR_SIZE_8M 3 -+ #define APBBR_SIZE_16M 4 -+ #define APBBR_SIZE_32M 5 -+ #define APBBR_SIZE_64M 6 -+ #define APBBR_SIZE_128M 7 -+ #define APBBR_SIZE_256M 8 -+ -+#define APBBR_SLAVE_BASE_MASK 0x3ff00000 -+#define APBBR_SLAVE_BASE_SHIFT 20 -+ -+/* APBBR DMA channel transfer cycles register -+ * DMA cycles (data size), 1 or 4 bus data transfer cycles per DMA cycle -+ * => transfer size = cycles * data_width * burst(1 or 4) -+ * so, max = 16M*4*4 = 256M -+ */ -+#define APBBR_DMA_CYC_MASK 0x00ffffff -+#define APBBR_DMA_CYC_SHIFT 0 -+ -+/* APBBR DMA channel command register */ -+#define APBBR_DMA_CHEN_MASK 0x00000001 -+#define APBBR_DMA_CHEN_BIT 0 -+ -+#define APBBR_DMA_FINTST_MASK 0x00000002 -+#define APBBR_DMA_FINTST_BIT 1 -+#define APBBR_DMA_FINTEN_MASK 0x00000004 -+#define APBBR_DMA_FINTEN_BIT 2 -+ -+#define APBBR_DMA_BURST_MASK 0x00000008 -+#define APBBR_DMA_BURST_BIT 3 -+ -+#define APBBR_DMA_ERRINTST_MASK 0x00000010 -+#define APBBR_DMA_ERRINTST_BIT 4 -+#define APBBR_DMA_ERRINTEN_MASK 0x00000020 -+#define APBBR_DMA_ERRINTEN_BIT 5 -+ -+#define APBBR_DMA_SRCADDRSEL_MASK 0x00000040 -+#define APBBR_DMA_SRCADDRSEL_BIT 6 -+#define APBBR_DMA_DSTADDRSEL_MASK 0x00000080 -+#define APBBR_DMA_DSTADDRSEL_BIT 7 -+ #define APBBR_ADDRSEL_APB 0 -+ #define APBBR_ADDRSEL_AHB 1 -+ -+#define APBBR_DMA_SRCADDRINC_MASK 0x00000700 -+#define APBBR_DMA_SRCADDRINC_SHIFT 8 -+#define APBBR_DMA_DSTADDRINC_MASK 0x00007000 -+#define APBBR_DMA_DSTADDRINC_SHIFT 12 -+ #define APBBR_ADDRINC_FIXED 0 /* no increment */ -+ #define APBBR_ADDRINC_I1X 1 /* +1, +4 (burst) */ -+ #define APBBR_ADDRINC_I2X 2 /* +2, +8 (burst) */ -+ #define APBBR_ADDRINC_I4X 3 /* +4, +16 (burst) */ -+ #define APBBR_ADDRINC_D1 5 /* -1 */ -+ #define APBBR_ADDRINC_D2 6 /* -2 */ -+ #define APBBR_ADDRINC_D4 7 /* -4 */ -+ -+#define APBBR_DMA_DREQSEL_MASK 0x000f0000 -+#define APBBR_DMA_DREQSEL_SHIFT 16 -+#define APBBR_DMA_SREQSEL_MASK 0x0f000000 -+#define APBBR_DMA_SREQSEL_SHIFT 24 -+ -+#ifdef CONFIG_PLAT_AG102 -+ #define APBBR_REQN_NONE 0 -+ #define APBBR_REQN_CFC 1 -+ #define APBBR_REQN_SSP 2 -+ #define APBBR_REQN_SDC 8 -+ #define APBBR_REQN_I2SAC97TX 6 -+ #define APBBR_REQN_SSP2 8 -+ #define APBBR_REQN_STUART 9 -+ #define APBBR_REQN_BTUART 10 -+ #define APBBR_REQN_IRDA 11 -+ #define APBBR_REQN_SMMC 12 -+// #define APBBR_REQN_USB 0 -+ #define APBBR_REQN_I2SAC97RX 13 -+ #define APBBR_REQN_FUSB220 14 -+ #define APBBR_REQN_MMSC 15 -+ #define APBBR_REQN_MAX 15 -+#else -+ #define APBBR_REQN_NONE 0 -+ #define APBBR_REQN_CFC 1 -+ #define APBBR_REQN_SSP 2 -+ #define APBBR_REQN_SDC 5 -+/* for amerald sd */ -+ #define APBBR_REQN_SDC_AMERALD 7 -+/* for amerald ac97 ssp2 */ -+ #define APBBR_REQN_I2SAC97TX_AMERALD 8 -+ #define APBBR_REQN_I2SAC97RX_AMERALD 9 -+ -+ #define APBBR_REQN_I2SAC97TX 6 -+ #define APBBR_REQN_SSP2 8 -+ #define APBBR_REQN_STUART 9 /* UART1 ? */ -+ #define APBBR_REQN_BTUART 10 /* UART2 ? */ -+ #define APBBR_REQN_IRDA 11 -+ #define APBBR_REQN_SMMC 12 -+ //#define APBBR_REQN_USB 13 -+ #define APBBR_REQN_I2SAC97RX 13 -+ #define APBBR_REQN_FUSB220 14 -+ #define APBBR_REQN_MMSC 15 -+ #define APBBR_REQN_MAX 15 -+#endif -+ -+#define APBBR_DMA_DATAWIDTH_MASK 0x00300000 /* Data width of transfer */ -+#define APBBR_DMA_DATAWIDTH_SHIFT 20 -+ #define APBBR_DATAWIDTH_4 0 /* word */ -+ #define APBBR_DATAWIDTH_2 1 /* half-word */ -+ #define APBBR_DATAWIDTH_1 2 /* byte */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+#define APBBR_DMA_CYCLE_TO_BYTES(cycle, width) ((cycle) << (2-(width))) -+#define APBBR_DMA_BYTES_TO_CYCLE(bytes, width) ((bytes) >> (2-(width))) -+#else -+#define APBBR_DMA_CYCLE_TO_BYTES(cycle, width) 0 -+#define APBBR_DMA_BYTES_TO_CYCLE(bytes, width) 0 -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+ -+#ifdef CONFIG_PLAT_AG102 -+ -+/***************************************************************************** -+ * PCU - AG102 Core APB -+*****************************************************************************/ -+/* Device base address */ -+#define PCU_BASE PCU_VA_BASE -+/* PMU registers (32-bit width) */ -+/* Add by Dennis on 2011.03.09 */ -+#define PCU_DMA_SEL (PCU_BASE+ 0x38) -+ -+#else /* CONFIG_PLAT_AG102 */ -+ -+/***************************************************************************** -+ * PMU - AG101 Core APB -+*****************************************************************************/ -+/* Device base address */ -+#define PMU_BASE PMU_FTPMU010_0_VA_BASE -+ -+/* PMU registers (32-bit width) */ -+#define PMU_AHBDMA_REQACK (PMU_BASE + 0x90) -+ -+#define PMU_CFC_REQACK_CFG (PMU_BASE + 0xa0) -+#define PMU_SSP1_REQACK_CFG (PMU_BASE + 0xa4) -+#define PMU_UART1TX_REQACK_CFG (PMU_BASE + 0xa8) -+#define PMU_UART1RX_REQACK_CFG (PMU_BASE + 0xac) -+#define PMU_UART2TX_REQACK_CFG (PMU_BASE + 0xb0) -+#define PMU_UART2RX_REQACK_CFG (PMU_BASE + 0xb4) -+#define PMU_SDC_REQACK_CFG (PMU_BASE + 0xb8) -+#define PMU_I2SAC97TX_REQACK_CFG (PMU_BASE + 0xbc) -+#define PMU_I2SAC97RX_REQACK_CFG (PMU_BASE + 0xc4) -+#define PMU_UART3TX_REQACK_CFG (PMU_BASE + 0xc0) -+#define PMU_UART3RX_REQACK_CFG (PMU_BASE + 0xcc) -+#define PMU_USB_REQACK_CFG (PMU_BASE + 0xc8) -+#define PMU_IRDA_REQACK_CFG (PMU_BASE + 0xd0) -+#define PMU_EXT0_REQACK_CFG (PMU_BASE + 0xd4) -+#define PMU_EXT1_REQACK_CFG (PMU_BASE + 0xd8) -+ -+ -+/***************************************************************************** -+ * PMU - AG101 Core APB -+*****************************************************************************/ -+ -+/* Driving capability and slew rate control register 2 (+0x48) */ -+#define PMU_STUART_DCSR_MASK 0x0000000f -+#define PMU_STUART_DCSR_SHIFT 0 -+#define PMU_BTUART_DCSR_MASK 0x00000f00 -+#define PMU_BTUART_DCSR_SHIFT 8 -+/*#define PMU_FFUART_DCSR_MASK 0x0000f000*/ -+/*#define PMU_FFUART_DCSR_SHIFT 12 */ -+#define PMU_PMU_DCSR_MASK 0x000f0000 -+#define PMU_PMU_DCSR_SHIFT 16 -+#define PMU_I2SAC97_DCSR_MASK 0x00f00000 -+#define PMU_I2SAC97_DCSR_SHIFT 20 -+#define PMU_SSP_DCSR_MASK 0x0f000000 -+#define PMU_SSP_DCSR_SHIFT 24 -+#define PMU_SD_DCSR_MASK 0xf0000000 -+#define PMU_SD_DCSR_SHIFT 28 -+ -+/* AHB DMA REQ/ACK connection configuration status register (+0x90) */ -+#define PMU_CH0_REQACK_MASK 0x0000000f -+#define PMU_CH0_REQACK_SHIFT 0 -+#define PMU_CH1_REQACK_MASK 0x000000f0 -+#define PMU_CH1_REQACK_SHIFT 4 -+#define PMU_CH2_REQACK_MASK 0x00000f00 -+#define PMU_CH2_REQACK_SHIFT 8 -+#define PMU_CH3_REQACK_MASK 0x0000f000 -+#define PMU_CH3_REQACK_SHIFT 12 -+#define PMU_CH4_REQACK_MASK 0x000f0000 -+#define PMU_CH4_REQACK_SHIFT 16 -+#define PMU_CH5_REQACK_MASK 0x00f00000 -+#define PMU_CH5_REQACK_SHIFT 20 -+#define PMU_CH6_REQACK_MASK 0x0f000000 -+#define PMU_CH6_REQACK_SHIFT 24 -+#define PMU_CH7_REQACK_MASK 0xf0000000 -+#define PMU_CH7_REQACK_SHIFT 28 -+ -+ #define PMU_REQN_NONE 0 -+ #define PMU_REQN_CFC 1 -+ #define PMU_REQN_SSP 2 -+ #define PMU_REQN_UART1TX 3 -+ #define PMU_REQN_UART1RX 4 -+ #define PMU_REQN_UART2TX 5 -+ #define PMU_REQN_UART2RX 6 -+ #define PMU_REQN_SDC 7 -+ #define PMU_REQN_I2SAC97TX 8 -+ #define PMU_REQN_I2SAC97RX 10 -+/* for amerald ac97 ssp2 */ -+ #define PMU_REQN_I2SAC97TX_AMERALD 8 -+ #define PMU_REQN_I2SAC97RX_AMERALD 9 -+ #define PMU_REQN_USB 11 -+ #define PMU_REQN_EXT0 14 -+ #define PMU_REQN_EXT1 15 -+ #define PMU_REQN_MAX 15 -+ -+/* CFC ..., etc, REQ/ACK connection configuration registers (0xa0 ~ 0xd8) */ -+#define PMU_CHANNEL_MASK 0x00000007 -+#define PMU_CHANNEL_SHIFT 0 -+#define PMU_DMACUSED_MASK 0x00000008 -+#define PMU_DMACUSED_BIT 3 -+ -+#endif /* CONFIG_PLAT_AG102 */ -+ -+ -+/***************************************************************************** -+ * DMAD globals section -+ */ -+ -+enum DMAD_DMAC_CORE { -+ DMAD_DMAC_AHB_CORE, -+ DMAD_DMAC_APB_CORE -+}; -+ -+enum DMAD_CHREG_FLAGS { -+ DMAD_FLAGS_NON_BLOCK = 0x00000000, -+ DMAD_FLAGS_SLEEP_BLOCK = 0x00000001, -+ DMAD_FLAGS_SPIN_BLOCK = 0x00000002, -+ DMAD_FLAGS_RING_MODE = 0x00000008, /* ring submission mode */ -+ DMAD_FLAGS_BIDIRECTION = 0x00000010, /* indicates both tx and rx */ -+}; -+ -+enum DMAD_CHDIR -+{ -+ DMAD_DIR_A0_TO_A1 = 0, -+ DMAD_DIR_A1_TO_A0 = 1, -+}; -+ -+/* AHB Channel Request -+ * -+ * Notes for developers: -+ * These should be channel-only properties. Controller-specific properties -+ * should be separated as other driver structure or driver buildin-hardcode. -+ * If controller properties are embeded in this union, request for a channel -+ * may unexpectedly override the controller setting of the request of other -+ * channels. -+ */ -+typedef struct dmad_ahb_chreq -+{ -+ /* channel property */ -+ u32 sync; /* (in) different clock domain */ -+ u32 priority; /* (in) DMAC_CSR_CHPRI_xxx */ -+ u32 hw_handshake; /* (in) hardware handshaking on/off */ -+ u32 burst_size; /* (in) DMAC_CSR_SIZE_xxx */ -+ -+ /* source property */ -+ union { -+ u32 src_width; /* (in) DMAC_CSR_WIDTH_xxx */ -+ u32 addr0_width; /* (in) bi-direction mode alias */ -+ u32 ring_width; /* (in) ring-mode alias */ -+ }; -+ union { -+ u32 src_ctrl; /* (in) DMAC_CSR_AD_xxx */ -+ u32 addr0_ctrl; /* (in) bi-direction mode alias */ -+ u32 ring_ctrl; /* (in) ring-mode alias */ -+ }; -+ union { -+ u32 src_reqn; /* (in) DMAC_REQN_xxx */ -+ u32 addr0_reqn; /* (in) bi-direction mode alias */ -+ u32 ring_reqn; /* (in) ring-mode alias */ -+ }; -+ -+ /* destination property */ -+ union { -+ u32 dst_width; /* (in) DMAC_CSR_WIDTH_xxx */ -+ u32 addr1_width; /* (in) bi-direction mode alias */ -+ u32 dev_width; /* (in) ring-mode alias */ -+ }; -+ union { -+ u32 dst_ctrl; /* (in) DMAC_CSR_AD_xxx */ -+ u32 addr1_ctrl; /* (in) bi-direction mode alias */ -+ u32 dev_ctrl; /* (in) ring-mode alias */ -+ }; -+ union { -+ u32 dst_reqn; /* (in) DMAC_REQN_xxx */ -+ u32 addr1_reqn; /* (in) bi-direction mode alias */ -+ u32 dev_reqn; /* (in) ring-mode alias */ -+ }; -+ -+ /* (in) transfer direction, valid only if following flags were set ... -+ * DMAD_FLAGS_BIDIRECTION or -+ * DMAD_FLAGS_RING_MODE -+ * value: -+ * 0 (addr0 -> addr1, or ring-buff to device) -+ * 1 (addr0 <- addr1, or device to ring-buff) -+ */ -+ u32 tx_dir; -+ -+} dmad_ahb_chreq; -+ -+/* APB Channel Request -+ * -+ * Notes for developers: -+ * These should be channel-only properties. Controller-specific properties -+ * should be separated as other driver structure or driver buildin-hardcode. -+ * If controller properties are embeded in this union, request for a channel -+ * may unexpectedly override the controller setting of the request of other -+ * channels. -+ */ -+typedef struct dmad_apb_chreq -+{ -+ /* controller property (removed! should not exist in this struct) */ -+ -+ /* channel property */ -+ u32 burst_mode; /* (in) Burst mode (0/1) */ -+ u32 data_width; /* (in) APBBR_DATAWIDTH_xxx */ -+ -+ /* source property */ -+ union { -+ u32 src_ctrl; /* (in) APBBR_ADDRINC_xxx */ -+ u32 addr0_ctrl; /* (in) bi-direction mode alias */ -+ u32 ring_ctrl; /* (in) ring-mode alias */ -+ }; -+ union { -+ u32 src_reqn; /* (in) APBBR_REQN_xxx */ -+ u32 addr0_reqn; /* (in) bi-direction mode alias */ -+ u32 ring_reqn; /* (in) ring-mode alias */ -+ }; -+ -+ /* destination property */ -+ union { -+ u32 dst_ctrl; /* (in) APBBR_ADDRINC_xxx */ -+ u32 addr1_ctrl; /* (in) bi-direction mode alias */ -+ u32 dev_ctrl; /* (in) ring-mode alias */ -+ }; -+ union { -+ u32 dst_reqn; /* (in) APBBR_REQN_xxx */ -+ u32 addr1_reqn; /* (in) bi-direction mode alias */ -+ u32 dev_reqn; /* (in) ring-mode alias */ -+ }; -+ -+ /* (in) transfer direction, valid only if following flags were set ... -+ * DMAD_FLAGS_BIDIRECTION or -+ * DMAD_FLAGS_RING_MODE -+ * value: -+ * 0 (addr0 -> addr1, or ring-buff to device) -+ * 1 (addr0 <- addr1, or device to ring-buff) -+ */ -+ u32 tx_dir; -+ -+} dmad_apb_chreq; -+ -+/* Channel Request Descriptor */ -+typedef struct dmad_chreq -+{ -+ /* common fields */ -+ u32 controller; /* (in) enum DMAD_DMAC_CORE */ -+ u32 flags; /* (in) enum DMAD_CHREQ_FLAGS */ -+ -+ /********************************************************************** -+ * ring mode specific fields (valid only for DMAD_FLAGS_RING_MODE) -+ * note: -+ * - size fields are in unit of data width -+ * * for AHB, ring size is limited to 4K * data_width of data if -+ * hw-LLP is not used -+ * * for AHB, ring size is limited to 4K * data_width * LLP-count -+ * hw-if LLP is used -+ * * for APB, ring size is limited to 16M * data_width of data -+ * - currently sw ring mode dma supports only fixed or incremental -+ * src/dst addressing -+ * - ring_size shoule >= periods * period_size -+ */ -+ dma_addr_t ring_base; /* (in) ring buffer base (pa) */ -+ dma_addr_t ring_size; /* (in) unit of data width */ -+ addr_t dev_addr; /* (in) device data port address */ -+ dma_addr_t periods; /* (in) number of ints per ring */ -+ dma_addr_t period_size; /* (in) size per int, data-width */ -+ -+ -+ /* channel-wise completion callback - called when hw-ptr catches sw-ptr -+ * (i.e., channel stops) -+ * -+ * completion_cb: (in) client supplied callback function, executed in -+ * interrupt context. -+ * completion_data: (in) client private data to be passed to data -+ * argument of completion_cb(). -+ */ -+ void (*completion_cb)(int channel, u16 status, void *data); -+ void *completion_data; -+ /*********************************************************************/ -+ -+ /* channel allocation output */ -+ u32 channel; /* (out) allocated channel */ -+ void *drq; /* (out) internal use (DMAD_DRQ *)*/ -+ -+ /* channel-alloc parameters (channel-wise properties) */ -+ union { -+#ifdef CONFIG_PLATFORM_AHBDMA -+ dmad_ahb_chreq ahb_req; /* (in) for AHB DMA parameters */ -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ dmad_apb_chreq apb_req; /* (in) APB Bridge DMA params */ -+#endif -+ }; -+ -+} dmad_chreq; -+ -+/* drb states are mutual exclusive */ -+enum DMAD_DRB_STATE -+{ -+ DMAD_DRB_STATE_FREE = 0, -+ DMAD_DRB_STATE_READY = 0x00000001, -+ DMAD_DRB_STATE_SUBMITTED = 0x00000002, -+ DMAD_DRB_STATE_EXECUTED = 0x00000004, -+ DMAD_DRB_STATE_COMPLETED = 0x00000008, -+ //DMAD_DRB_STATE_ERROR = 0x00000010, -+ DMAD_DRB_STATE_ABORT = 0x00000020, -+}; -+ -+/* DMA request block -+ * todo: replaced link with kernel struct list_head ?? -+ */ -+typedef struct dmad_drb -+{ -+ u32 prev; /* (internal) previous node */ -+ u32 next; /* (internal) next node */ -+ u32 node; /* (internal) this node */ -+ -+ u32 state; /* (out) DRB's current state */ -+ -+ union { -+ dma_addr_t src_addr; /* (in) source pa */ -+ dma_addr_t addr0; /* (in) bi-direction mode alias */ -+ }; -+ -+ union { -+ dma_addr_t dst_addr; /* (in) destination pa */ -+ dma_addr_t addr1; /* (in) bi-direction mode alias */ -+ }; -+ -+ /* (in) AHB DMA (22 bits): 0 ~ 4M-1, unit is "data width" -+ * APB DMA (24 bits): 0 ~ 16M-1, unit is "data width * burst size" -+ * => for safe without mistakes, use dmad_make_req_cycles() to -+ * compose this value if the addressing mode is incremental -+ * mode (not working yet for decremental mode). -+ */ -+ dma_addr_t req_cycle; -+ -+ /* (in) if non-null, this sync object will be signaled upon dma -+ * completion (for blocked-waiting dma completion) -+ */ -+ struct completion *sync; -+ -+} dmad_drb; -+ -+ -+/****************************************************************************** -+ * Debug Trace Mechanism -+ */ -+#if (DMAD_ERROR_TRACE) -+#define dmad_err(format, arg...) printk(KERN_ERR format , ## arg) -+#else -+#define dmad_err(format, arg...) (void)(0) -+#endif -+ -+#if (DMAD_DEBUG_TRACE) -+#define dmad_dbg(format, arg...) printk(KERN_INFO format , ## arg) -+#else -+#define dmad_dbg(format, arg...) (void)(0) -+#endif -+ -+#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) -+ -+/****************************************************************************** -+ * DMAD Driver Interface -+******************************************************************************/ -+ -+extern int dmad_channel_alloc(dmad_chreq *ch_req); -+extern int dmad_channel_free(dmad_chreq *ch_req); -+extern int dmad_channel_enable(const dmad_chreq *ch_req, u8 enable); -+extern u32 dmad_max_size_per_drb(dmad_chreq *ch_req); -+extern u32 dmad_bytes_to_cycles(dmad_chreq *ch_req, u32 byte_size); -+ -+extern int dmad_kickoff_requests(dmad_chreq *ch_req); -+extern int dmad_drain_requests(dmad_chreq *ch_req, u8 shutdown); -+ -+/* for performance reason, these two functions are platform-specific */ -+#ifdef CONFIG_PLATFORM_AHBDMA -+extern int dmad_probe_irq_source_ahb(void); -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+extern int dmad_probe_irq_source_apb(void); -+#endif -+ -+/* note: hw_ptr here is phyical address of dma source or destination */ -+extern dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq *ch_req); -+extern dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq *ch_req); -+ -+/***************************************************************************** -+ * routines only valid in discrete (non-ring) mode -+ */ -+extern int dmad_config_channel_dir(dmad_chreq *ch_req, u8 dir); -+extern int dmad_alloc_drb(dmad_chreq *ch_req, dmad_drb **drb); -+extern int dmad_free_drb(dmad_chreq *ch_req, dmad_drb *drb); -+extern int dmad_submit_request(dmad_chreq *ch_req, -+ dmad_drb *drb, u8 keep_fired); -+extern int dmad_withdraw_request(dmad_chreq *ch_req, dmad_drb *drb); -+/****************************************************************************/ -+ -+/***************************************************************************** -+ * routines only valid in ring mode -+ * note: sw_ptr and hw_ptr are values offset from the ring buffer base -+ * unit of sw_ptr is data-width -+ * unit of hw_ptr returned is byte -+ */ -+extern int dmad_update_ring(dmad_chreq *ch_req); -+extern int dmad_update_ring_sw_ptr(dmad_chreq *ch_req, -+ dma_addr_t sw_ptr, u8 keep_fired); -+extern dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq *ch_req); -+/****************************************************************************/ -+ -+#else /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */ -+ -+static inline int dmad_channel_alloc(dmad_chreq *ch_req) { return -EFAULT; } -+static inline int dmad_channel_free(dmad_chreq *ch_req) { return -EFAULT; } -+static inline int dmad_channel_enable(const dmad_chreq *ch_req, u8 enable) -+ { return -EFAULT; } -+static inline u32 dmad_max_size_per_drb(dmad_chreq *ch_req) { return 0; } -+static inline u32 dmad_bytes_to_cycles(dmad_chreq *ch_req, u32 byte_size) -+ { return 0; } -+static inline int dmad_kickoff_requests(dmad_chreq *ch_req) { return -EFAULT; } -+static inline int dmad_drain_requests(dmad_chreq *ch_req, u8 shutdown) -+ { return -EFAULT; } -+static inline int dmad_probe_irq_source_ahb(void) { return -EFAULT; } -+static inline int dmad_probe_irq_source_apb(void) { return -EFAULT; } -+static inline dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq *ch_req) -+ { return (dma_addr_t)NULL; } -+static inline dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq *ch_req) -+ { return (dma_addr_t)NULL; } -+static inline int dmad_config_channel_dir(dmad_chreq *ch_req, u8 dir) -+ { return -EFAULT; } -+static inline int dmad_alloc_drb(dmad_chreq *ch_req, dmad_drb **drb) -+ { return -EFAULT; } -+static inline int dmad_free_drb(dmad_chreq *ch_req, dmad_drb *drb) -+ { return -EFAULT; } -+static inline int dmad_submit_request(dmad_chreq *ch_req, -+ dmad_drb *drb, u8 keep_fired) { return -EFAULT; } -+static inline int dmad_withdraw_request(dmad_chreq *ch_req, dmad_drb *drb) -+ { return -EFAULT; } -+static inline int dmad_update_ring(dmad_chreq *ch_req) -+ { return -EFAULT; } -+static inline int dmad_update_ring_sw_ptr(dmad_chreq *ch_req, -+ dma_addr_t sw_ptr, u8 keep_fired) { return -EFAULT; } -+static inline dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq *ch_req) -+ { return (dma_addr_t)NULL; } -+ -+#endif /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */ -+ -+#endif /* __NDS_DMAD_INC__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/dma.h linux-3.4.113/arch/nds32/include/asm/dma.h ---- linux-3.4.113.orig/arch/nds32/include/asm/dma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/dma.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,17 @@ -+/* -+ * linux/arch/nds32/include/asm/dma.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_DMA_H__ -+#define __NDS32_DMA_H__ -+ -+#define MAX_DMA_ADDRESS 0xffffffff -+ -+#ifdef CONFIG_PCI -+extern int isa_dma_bridge_buggy; -+#else -+#define isa_dma_bridge_buggy (0) -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/dma-mapping.h linux-3.4.113/arch/nds32/include/asm/dma-mapping.h ---- linux-3.4.113.orig/arch/nds32/include/asm/dma-mapping.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/dma-mapping.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,453 @@ -+/* -+ * linux/arch/nds32/include/asm/dma-mapping.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef ASMNDS32_DMA_MAPPING_H -+#define ASMNDS32_DMA_MAPPING_H -+ -+#ifdef __KERNEL__ -+ -+#include /* need struct page */ -+#include -+ -+#include -+ -+/* -+ * DMA-consistent mapping functions. These allocate/free a region of -+ * uncached, unwrite-buffered mapped memory space for use with DMA -+ * devices. This is the "generic" version. The PCI specific version -+ * is in pci.h -+ */ -+extern void consistent_sync(void *kaddr, size_t size, int rw); -+ -+/* -+ * Return whether the given device DMA address mask can be supported -+ * properly. For example, if your device can only drive the low 24-bits -+ * during bus mastering, then you would pass 0x00ffffff as the mask -+ * to this function. -+ */ -+static inline int dma_supported(struct device *dev, u64 mask) -+{ -+ return dev->dma_mask && *dev->dma_mask != 0; -+} -+ -+static inline int dma_set_mask(struct device *dev, u64 dma_mask) -+{ -+ if (!dev->dma_mask || !dma_supported(dev, dma_mask)) -+ return -EIO; -+ -+ *dev->dma_mask = dma_mask; -+ -+ return 0; -+} -+ -+static inline int dma_is_consistent(dma_addr_t handle) -+{ -+ return 0; -+} -+ -+/* -+ * DMA errors are defined by all-bits-set in the DMA address. -+ */ -+static inline int dma_mapping_error(struct device *dev, dma_addr_t dma_addr) -+{ -+ return dma_addr == ~0; -+} -+ -+/* -+ * Dummy noncoherent implementation. We don't provide a dma_cache_sync -+ * function so drivers using this API are highlighted with build warnings. -+ */ -+static inline void * -+dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp) -+{ -+ return NULL; -+} -+ -+static inline void -+dma_free_noncoherent(struct device *dev, size_t size, void *cpu_addr, -+ dma_addr_t handle) -+{ -+} -+ -+/** -+ * dma_alloc_coherent - allocate consistent memory for DMA -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @size: required memory size -+ * @handle: bus-specific DMA address -+ * -+ * Allocate some uncached, unbuffered memory for a device for -+ * performing DMA. This function allocates pages, and will -+ * return the CPU-viewed address, and sets @handle to be the -+ * device-viewed address. -+ */ -+extern void * -+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp); -+ -+/** -+ * dma_free_coherent - free memory allocated by dma_alloc_coherent -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @size: size of memory originally requested in dma_alloc_coherent -+ * @cpu_addr: CPU-view address returned from dma_alloc_coherent -+ * @handle: device-view address returned from dma_alloc_coherent -+ * -+ * Free (and unmap) a DMA buffer previously allocated by -+ * dma_alloc_coherent(). -+ * -+ * References to memory and mappings associated with cpu_addr/handle -+ * during and after this call executing are illegal. -+ */ -+extern void -+dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, -+ dma_addr_t handle); -+ -+/** -+ * dma_mmap_coherent - map a coherent DMA allocation into user space -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @vma: vm_area_struct describing requested user mapping -+ * @cpu_addr: kernel CPU-view address returned from dma_alloc_coherent -+ * @handle: device-view address returned from dma_alloc_coherent -+ * @size: size of memory originally requested in dma_alloc_coherent -+ * -+ * Map a coherent DMA buffer previously allocated by dma_alloc_coherent -+ * into user space. The coherent DMA buffer must not be freed by the -+ * driver until the user space mapping has been released. -+ */ -+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t handle, size_t size); -+ -+ -+/** -+ * dma_alloc_writecombine - allocate writecombining memory for DMA -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @size: required memory size -+ * @handle: bus-specific DMA address -+ * -+ * Allocate some uncached, buffered memory for a device for -+ * performing DMA. This function allocates pages, and will -+ * return the CPU-viewed address, and sets @handle to be the -+ * device-viewed address. -+ */ -+extern void * -+dma_alloc_writecombine(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp); -+ -+#define dma_free_writecombine(dev,size,cpu_addr,handle) \ -+ dma_free_coherent(dev,size,cpu_addr,handle) -+ -+int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t handle, size_t size); -+ -+ -+/** -+ * dma_map_single - map a single buffer for streaming DMA -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @cpu_addr: CPU direct mapped address of buffer -+ * @size: size of buffer to map -+ * @dir: DMA transfer direction -+ * -+ * Ensure that any data held in the cache is appropriately discarded -+ * or written back. -+ * -+ * The device owns this memory once this call has completed. The CPU -+ * can regain ownership by calling dma_unmap_single() or -+ * dma_sync_single_for_cpu(). -+ */ -+#ifndef CONFIG_DMABOUNCE -+static inline dma_addr_t -+dma_map_single(struct device *dev, void *cpu_addr, size_t size, -+ enum dma_data_direction dir) -+{ -+ consistent_sync(cpu_addr, size, dir); -+ return virt_to_dma(dev, (unsigned long)cpu_addr); -+} -+#else -+extern dma_addr_t dma_map_single(struct device *,void *, size_t, enum dma_data_direction); -+#endif -+ -+/** -+ * dma_map_page - map a portion of a page for streaming DMA -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @page: page that buffer resides in -+ * @offset: offset into page for start of buffer -+ * @size: size of buffer to map -+ * @dir: DMA transfer direction -+ * -+ * Ensure that any data held in the cache is appropriately discarded -+ * or written back. -+ * -+ * The device owns this memory once this call has completed. The CPU -+ * can regain ownership by calling dma_unmap_page() or -+ * dma_sync_single_for_cpu(). -+ */ -+static inline dma_addr_t -+dma_map_page(struct device *dev, struct page *page, -+ unsigned long offset, size_t size, -+ enum dma_data_direction dir) -+{ -+ return dma_map_single(dev, page_address(page) + offset, size, (int)dir); -+} -+ -+/** -+ * dma_unmap_single - unmap a single buffer previously mapped -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @handle: DMA address of buffer -+ * @size: size of buffer to map -+ * @dir: DMA transfer direction -+ * -+ * Unmap a single streaming mode DMA translation. The handle and size -+ * must match what was provided in the previous dma_map_single() call. -+ * All other usages are undefined. -+ * -+ * After this call, reads by the CPU to the buffer are guaranteed to see -+ * whatever the device wrote there. -+ */ -+#ifndef CONFIG_DMABOUNCE -+static inline void -+dma_unmap_single(struct device *dev, dma_addr_t handle, size_t size, -+ enum dma_data_direction dir) -+{ -+ /* nothing to do */ -+} -+#else -+extern void dma_unmap_single(struct device *, dma_addr_t, size_t, enum dma_data_direction); -+#endif -+ -+/** -+ * dma_unmap_page - unmap a buffer previously mapped through dma_map_page() -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @handle: DMA address of buffer -+ * @size: size of buffer to map -+ * @dir: DMA transfer direction -+ * -+ * Unmap a single streaming mode DMA translation. The handle and size -+ * must match what was provided in the previous dma_map_single() call. -+ * All other usages are undefined. -+ * -+ * After this call, reads by the CPU to the buffer are guaranteed to see -+ * whatever the device wrote there. -+ */ -+static inline void -+dma_unmap_page(struct device *dev, dma_addr_t handle, size_t size, -+ enum dma_data_direction dir) -+{ -+ dma_unmap_single(dev, handle, size, (int)dir); -+} -+ -+/** -+ * dma_map_sg - map a set of SG buffers for streaming mode DMA -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @sg: list of buffers -+ * @nents: number of buffers to map -+ * @dir: DMA transfer direction -+ * -+ * Map a set of buffers described by scatterlist in streaming -+ * mode for DMA. This is the scatter-gather version of the -+ * above dma_map_single interface. Here the scatter gather list -+ * elements are each tagged with the appropriate dma address -+ * and length. They are obtained via sg_dma_{address,length}(SG). -+ * -+ * NOTE: An implementation may be able to use a smaller number of -+ * DMA address/length pairs than there are SG table elements. -+ * (for example via virtual mapping capabilities) -+ * The routine returns the number of addr/length pairs actually -+ * used, at most nents. -+ * -+ * Device ownership issues as mentioned above for dma_map_single are -+ * the same here. -+ */ -+#ifndef CONFIG_DMABOUNCE -+static inline int -+dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ int i; -+ -+ for (i = 0; i < nents; i++, sg++) { -+ void *virt; -+ unsigned long pfn; -+ struct page *page = sg_page(sg); -+ -+ sg->dma_address = page_to_dma(dev, page) + sg->offset; -+ pfn = page_to_pfn(page) + sg->offset / PAGE_SIZE; -+ page = pfn_to_page(pfn); -+ if (PageHighMem(page)) { -+ virt = kmap_atomic(page); -+ consistent_sync(virt, sg->length, dir); -+ kunmap_atomic(virt); -+ } else { -+ if (sg->offset > PAGE_SIZE) -+ panic("sg->offset:%08x > PAGE_SIZE\n", sg->offset); -+ virt = page_address(page) + sg->offset; -+ consistent_sync(virt, sg->length, dir); -+ } -+ } -+ return nents; -+} -+#else -+extern int dma_map_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); -+#endif -+ -+/** -+ * dma_unmap_sg - unmap a set of SG buffers mapped by dma_map_sg -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @sg: list of buffers -+ * @nents: number of buffers to map -+ * @dir: DMA transfer direction -+ * -+ * Unmap a set of streaming mode DMA translations. -+ * Again, CPU read rules concerning calls here are the same as for -+ * dma_unmap_single() above. -+ */ -+#ifndef CONFIG_DMABOUNCE -+static inline void -+dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ -+ /* nothing to do */ -+} -+#else -+extern void dma_unmap_sg(struct device *, struct scatterlist *, int, enum dma_data_direction); -+#endif -+ -+ -+/** -+ * dma_sync_single_for_cpu -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @handle: DMA address of buffer -+ * @size: size of buffer to map -+ * @dir: DMA transfer direction -+ * -+ * Make physical memory consistent for a single streaming mode DMA -+ * translation after a transfer. -+ * -+ * If you perform a dma_map_single() but wish to interrogate the -+ * buffer using the cpu, yet do not wish to teardown the PCI dma -+ * mapping, you must call this function before doing so. At the -+ * next point you give the PCI dma address back to the card, you -+ * must first the perform a dma_sync_for_device, and then the -+ * device again owns the buffer. -+ */ -+#ifndef CONFIG_DMABOUNCE -+static inline void -+dma_sync_single_for_cpu(struct device *dev, dma_addr_t handle, size_t size, -+ enum dma_data_direction dir) -+{ -+ consistent_sync((void *)dma_to_virt(dev, handle), size, dir); -+} -+ -+static inline void -+dma_sync_single_for_device(struct device *dev, dma_addr_t handle, size_t size, -+ enum dma_data_direction dir) -+{ -+ consistent_sync((void *)dma_to_virt(dev, handle), size, dir); -+} -+#else -+extern void dma_sync_single_for_cpu(struct device*, dma_addr_t, size_t, enum dma_data_direction); -+extern void dma_sync_single_for_device(struct device*, dma_addr_t, size_t, enum dma_data_direction); -+#endif -+ -+ -+/** -+ * dma_sync_sg_for_cpu -+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices -+ * @sg: list of buffers -+ * @nents: number of buffers to map -+ * @dir: DMA transfer direction -+ * -+ * Make physical memory consistent for a set of streaming -+ * mode DMA translations after a transfer. -+ * -+ * The same as dma_sync_single_for_* but for a scatter-gather list, -+ * same rules and usage. -+ */ -+#ifndef CONFIG_DMABOUNCE -+static inline void -+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ int i; -+ -+ for (i = 0; i < nents; i++, sg++) { -+ char *virt = page_address( (struct page *)sg->page_link) + sg->offset; -+ consistent_sync(virt, sg->length, dir); -+ } -+} -+ -+static inline void -+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents, -+ enum dma_data_direction dir) -+{ -+ int i; -+ -+ for (i = 0; i < nents; i++, sg++) { -+ char *virt = page_address( (struct page *)sg->page_link) + sg->offset; -+ consistent_sync(virt, sg->length, dir); -+ } -+} -+#else -+extern void dma_sync_sg_for_cpu(struct device*, struct scatterlist*, int, enum dma_data_direction); -+extern void dma_sync_sg_for_device(struct device*, struct scatterlist*, int, enum dma_data_direction); -+#endif -+ -+#ifdef CONFIG_DMABOUNCE -+/* -+ * For SA-1111, IXP425, and ADI systems the dma-mapping functions are "magic" -+ * and utilize bounce buffers as needed to work around limited DMA windows. -+ * -+ * On the SA-1111, a bug limits DMA to only certain regions of RAM. -+ * On the IXP425, the PCI inbound window is 64MB (256MB total RAM) -+ * On some ADI engineering systems, PCI inbound window is 32MB (12MB total RAM) -+ * -+ * The following are helper functions used by the dmabounce subystem -+ * -+ */ -+ -+/** -+ * dmabounce_register_dev -+ * -+ * @dev: valid struct device pointer -+ * @small_buf_size: size of buffers to use with small buffer pool -+ * @large_buf_size: size of buffers to use with large buffer pool (can be 0) -+ * -+ * This function should be called by low-level platform code to register -+ * a device as requireing DMA buffer bouncing. The function will allocate -+ * appropriate DMA pools for the device. -+ * -+ */ -+extern int dmabounce_register_dev(struct device *, unsigned long, unsigned long); -+ -+/** -+ * dmabounce_unregister_dev -+ * -+ * @dev: valid struct device pointer -+ * -+ * This function should be called by low-level platform code when device -+ * that was previously registered with dmabounce_register_dev is removed -+ * from the system. -+ * -+ */ -+extern void dmabounce_unregister_dev(struct device *); -+ -+/** -+ * dma_needs_bounce -+ * -+ * @dev: valid struct device pointer -+ * @dma_handle: dma_handle of unbounced buffer -+ * @size: size of region being mapped -+ * -+ * Platforms that utilize the dmabounce mechanism must implement -+ * this function. -+ * -+ * The dmabounce routines call this function whenever a dma-mapping -+ * is requested to determine whether a given buffer needs to be bounced -+ * or not. The function must return 0 if the buffer is OK for -+ * DMA access and 1 if the buffer needs to be bounced. -+ * -+ */ -+extern int dma_needs_bounce(struct device*, dma_addr_t, size_t); -+#endif /* CONFIG_DMABOUNCE */ -+ -+#endif /* __KERNEL__ */ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/elf.h linux-3.4.113/arch/nds32/include/asm/elf.h ---- linux-3.4.113.orig/arch/nds32/include/asm/elf.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/elf.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,145 @@ -+/* -+ * linux/arch/nds32/include/asm/elf.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASMNDS32_ELF_H -+#define __ASMNDS32_ELF_H -+ -+/* -+ * ELF register definitions.. -+ */ -+ -+#include -+#include -+ -+typedef unsigned long elf_greg_t; -+typedef unsigned long elf_freg_t[3]; -+ -+extern unsigned int elf_hwcap; -+ -+#define EM_NDS32 167 -+ -+ -+#define R_NDS32_NONE 0 -+#define R_NDS32_16_RELA 19 -+#define R_NDS32_32_RELA 20 -+#define R_NDS32_9_PCREL_RELA 22 -+#define R_NDS32_15_PCREL_RELA 23 -+#define R_NDS32_17_PCREL_RELA 24 -+#define R_NDS32_25_PCREL_RELA 25 -+#define R_NDS32_HI20_RELA 26 -+#define R_NDS32_LO12S3_RELA 27 -+#define R_NDS32_LO12S2_RELA 28 -+#define R_NDS32_LO12S1_RELA 29 -+#define R_NDS32_LO12S0_RELA 30 -+#define R_NDS32_SDA15S3_RELA 31 -+#define R_NDS32_SDA15S2_RELA 32 -+#define R_NDS32_SDA15S1_RELA 33 -+#define R_NDS32_SDA15S0_RELA 34 -+#define R_NDS32_GOT20 37 -+#define R_NDS32_25_PLTREL 38 -+#define R_NDS32_COPY 39 -+#define R_NDS32_GLOB_DAT 40 -+#define R_NDS32_JMP_SLOT 41 -+#define R_NDS32_RELATIVE 42 -+#define R_NDS32_GOTOFF 43 -+#define R_NDS32_GOTPC20 44 -+#define R_NDS32_GOT_HI20 45 -+#define R_NDS32_GOT_LO12 46 -+#define R_NDS32_GOTPC_HI20 47 -+#define R_NDS32_GOTPC_LO12 48 -+#define R_NDS32_GOTOFF_HI20 49 -+#define R_NDS32_GOTOFF_LO12 50 -+#define R_NDS32_INSN16 51 -+#define R_NDS32_LABEL 52 -+#define R_NDS32_LONGCALL1 53 -+#define R_NDS32_LONGCALL2 54 -+#define R_NDS32_LONGCALL3 55 -+#define R_NDS32_LONGJUMP1 56 -+#define R_NDS32_LONGJUMP2 57 -+#define R_NDS32_LONGJUMP3 58 -+#define R_NDS32_LOADSTORE 59 -+#define R_NDS32_9_FIXED_RELA 60 -+#define R_NDS32_15_FIXED_RELA 61 -+#define R_NDS32_17_FIXED_RELA 62 -+#define R_NDS32_25_FIXED_RELA 63 -+#define R_NDS32_PLTREL_HI20 64 -+#define R_NDS32_PLTREL_LO12 65 -+#define R_NDS32_PLT_GOTREL_HI20 66 -+#define R_NDS32_PLT_GOTREL_LO12 67 -+#define R_NDS32_LO12S0_ORI_RELA 72 -+#define R_NDS32_DWARF2_OP1_RELA 77 -+#define R_NDS32_DWARF2_OP2_RELA 78 -+#define R_NDS32_DWARF2_LEB_RELA 79 -+#define R_NDS32_WORD_9_PCREL_RELA 94 -+#define R_NDS32_LONGCALL4 107 -+#define R_NDS32_RELA_NOP_MIX 192 -+#define R_NDS32_RELA_NOP_MAX 255 -+ -+#define ELF_NGREG (sizeof (struct pt_regs) / sizeof(elf_greg_t)) -+typedef elf_greg_t elf_gregset_t[ELF_NGREG]; -+ -+typedef struct user_fp elf_fpregset_t; -+ -+struct elf32_hdr; -+extern int elf_check_arch(const struct elf32_hdr *hdr); -+ -+/* -+ * These are used to set parameters in the core dumps. -+ */ -+#define ELF_CLASS ELFCLASS32 -+#ifdef __NDS32_EB__ -+#define ELF_DATA ELFDATA2MSB; -+#else -+#define ELF_DATA ELFDATA2LSB; -+#endif -+#define ELF_ARCH EM_NDS32 -+#define USE_ELF_CORE_DUMP -+#define ELF_EXEC_PAGESIZE PAGE_SIZE -+ -+/* This is the location that an ET_DYN program is loaded if exec'ed. Typical -+ use of this is to invoke "./ld.so someprog" to test out a new version of -+ the loader. We need to make sure that it is out of the way of the program -+ that it will "exec", and that there is sufficient room for the brk. */ -+ -+#define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) -+ -+/* When the program starts, a1 contains a pointer to a function to be -+ registered with atexit, as per the SVR4 ABI. A value of 0 means we -+ have no such handler. */ -+#define ELF_PLAT_INIT(_r, load_addr) (_r)->NDS32_r0 = 0 -+ -+/* This yields a mask that user programs can use to figure out what -+ instruction set this cpu supports. */ -+ -+#define ELF_HWCAP (elf_hwcap) -+ -+/* This yields a string that ld.so will use to load implementation -+ specific libraries for optimization. This is more specific in -+ intent than poking at uname or /proc/cpuinfo. */ -+ -+/* For now we just provide a fairly general string that describes the -+ processor family. This could be made more specific later if someone -+ implemented optimisations that require it. 26-bit CPUs give you -+ "v1l" for ARM2 (no SWP) and "v2l" for anything else (ARM1 isn't -+ supported). 32-bit CPUs give you "v3[lb]" for anything based on an -+ ARM6 or ARM7 core and "armv4[lb]" for anything based on a StrongARM-1 -+ core. */ -+ -+#define ELF_PLATFORM_SIZE 16 -+extern char elf_platform[]; -+#define ELF_PLATFORM (elf_platform) -+ -+#ifdef __KERNEL__ -+ -+/* Old NetWinder binaries were compiled in such a way that the iBCS -+ heuristic always trips on them. Until these binaries become uncommon -+ enough not to care, don't trust the `ibcs' flag here. In any case -+ there is no other ELF system currently supported by iBCS. -+ @@ Could print a warning message to encourage users to upgrade. */ -+#define SET_PERSONALITY(ex) set_personality(PER_LINUX) -+ -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/emergency-restart.h linux-3.4.113/arch/nds32/include/asm/emergency-restart.h ---- linux-3.4.113.orig/arch/nds32/include/asm/emergency-restart.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/emergency-restart.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/emergency-restart.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_EMERGENCY_RESTART_H__ -+#define __NDS32_EMERGENCY_RESTART_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/errno.h linux-3.4.113/arch/nds32/include/asm/errno.h ---- linux-3.4.113.orig/arch/nds32/include/asm/errno.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/errno.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/errno.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_ERRNO_H__ -+#define __NDS32_ERRNO_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/exec.h linux-3.4.113/arch/nds32/include/asm/exec.h ---- linux-3.4.113.orig/arch/nds32/include/asm/exec.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/exec.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,6 @@ -+#ifndef __ASM_NDS32_EXEC_H -+#define __ASM_NDS32_EXEC_H -+ -+#define arch_align_stack(x) (x) -+ -+#endif /* __ASM_ARM_EXEC_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/fb.h linux-3.4.113/arch/nds32/include/asm/fb.h ---- linux-3.4.113.orig/arch/nds32/include/asm/fb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/fb.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * linux/arch/nds32/include/asm/fb.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_FB_H__ -+#define __NDS32_FB_H__ -+ -+ -+#include -+#include -+#include -+ -+static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma, -+ unsigned long off) -+{ -+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+} -+ -+static inline int fb_is_primary_device(struct fb_info *info) -+{ -+ return 0; -+} -+ -+#endif /* __NDS32_FB_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/fcntl.h linux-3.4.113/arch/nds32/include/asm/fcntl.h ---- linux-3.4.113.orig/arch/nds32/include/asm/fcntl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/fcntl.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,37 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 1995, 96, 97, 98, 99, 2003, 05 Ralf Baechle -+ */ -+#ifndef _ASM_FCNTL_H -+#define _ASM_FCNTL_H -+ -+/* -+ * The flavours of struct flock. "struct flock" is the ABI compliant -+ * variant. Finally struct flock64 is the LFS variant of struct flock. As -+ * a historic accident and inconsistence with the ABI definition it doesn't -+ * contain all the same fields as struct flock. -+ */ -+ -+#ifdef CONFIG_32BIT -+#include -+ -+struct flock { -+ short l_type; -+ short l_whence; -+ off_t l_start; -+ off_t l_len; -+ long l_sysid; -+ __kernel_pid_t l_pid; -+ long pad[4]; -+}; -+ -+#define HAVE_ARCH_STRUCT_FLOCK -+ -+#endif /* CONFIG_32BIT */ -+ -+#include -+ -+#endif /* _ASM_FCNTL_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/fixmap.h linux-3.4.113/arch/nds32/include/asm/fixmap.h ---- linux-3.4.113.orig/arch/nds32/include/asm/fixmap.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/fixmap.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,88 @@ -+/* -+ * fixmap.h: compile-time virtual memory allocation -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 1998 Ingo Molnar -+ * -+ * Support of BIGMEM added by Gerhard Wichert, Siemens AG, July 1999 -+ */ -+ -+#ifndef __ASM_NDS32_FIXMAP_H -+#define __ASM_NDS32_FIXMAP_H -+ -+#ifdef CONFIG_HIGHMEM -+#include -+#include -+#endif -+ -+/* -+ * Here we define all the compile-time 'special' virtual -+ * addresses. The point is to have a constant address at -+ * compile time, but to set the physical address only -+ * in the boot process. We allocate these special addresses -+ * from the end of the consistent memory region backwards. -+ * Also this lets us do fail-safe vmalloc(), we -+ * can guarantee that these special addresses and -+ * vmalloc()-ed addresses never overlap. -+ * -+ * these 'compile-time allocated' memory buffers are -+ * fixed-size 4k pages. (or larger if used with an increment -+ * higher than 1) use fixmap_set(idx,phys) to associate -+ * physical memory with fixmap indices. -+ * -+ * TLB entries of such buffers will not be flushed across -+ * task switches. -+ */ -+enum fixed_addresses { -+ FIX_KMAP_RESERVED, -+ FIX_KMAP_BEGIN, -+#ifdef CONFIG_HIGHMEM -+ FIX_KMAP_END = FIX_KMAP_BEGIN + (KM_TYPE_NR * NR_CPUS), -+#endif -+#ifdef CONFIG_EARLY_PRINTK -+ FIX_EARLY_DEBUG, -+#endif -+ FIX_RETURN_SYSCALL, -+ __end_of_fixed_addresses -+}; -+#define FIXADDR_TOP ((unsigned long) (-(16 * PAGE_SIZE))) -+#define FIXADDR_SIZE ((__end_of_fixed_addresses) << PAGE_SHIFT) -+#define FIXADDR_START (FIXADDR_TOP - FIXADDR_SIZE) -+ -+#define __fix_to_virt(x) (FIXADDR_TOP - ((x) << PAGE_SHIFT)) -+#define __virt_to_fix(x) ((FIXADDR_TOP - ((x)&PAGE_MASK)) >> PAGE_SHIFT) -+ -+#define __this_fixmap_does_not_exist() WARN_ON(1) -+/* -+ * 'index to address' translation. If anyone tries to use the idx -+ * directly without tranlation, we catch the bug with a NULL-deference -+ * kernel oops. Illegal ranges of incoming indices are caught too. -+ */ -+ -+static inline unsigned long fix_to_virt(const unsigned int idx) -+{ -+ /* -+ * this branch gets completely eliminated after inlining, -+ * except when someone tries to use fixaddr indices in an -+ * illegal way. (such as mixing up address types or using -+ * out-of-range indices). -+ * -+ * If it doesn't get removed, the linker will complain -+ * loudly with a reasonably clear error message.. -+ */ -+ if (idx >= __end_of_fixed_addresses) -+ __this_fixmap_does_not_exist(); -+ -+ return __fix_to_virt(idx); -+} -+ -+static inline unsigned long virt_to_fix(const unsigned long vaddr) -+{ -+ BUG_ON(vaddr >= FIXADDR_TOP || vaddr < FIXADDR_START); -+ return __virt_to_fix(vaddr); -+} -+ -+#endif /* __ASM_NDS32_FIXMAP_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/fpu.h linux-3.4.113/arch/nds32/include/asm/fpu.h ---- linux-3.4.113.orig/arch/nds32/include/asm/fpu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/fpu.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,100 @@ -+/* -+ * linux/arch/nds32/include/asm/fpu.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_FPU_H -+#define __ASM_NDS32_FPU_H -+ -+#ifndef __ASSEMBLY__ -+#include -+#include -+ -+extern void save_fpu(struct task_struct *__tsk); -+extern void fpload(struct fpu_struct *fpregs); -+extern void do_fpu_exception(unsigned long error_code, struct pt_regs *regs); -+extern int do_fpu_inst(unsigned short, struct pt_regs *); -+ -+#ifdef CONFIG_FPU -+ -+#define test_tsk_fpu(regs) (regs->NDS32_FUCOP_CTL & FUCOP_CTL_mskCP0EN) -+ -+struct task_struct; -+ -+static inline void release_fpu(struct pt_regs *regs) -+{ -+ regs->NDS32_FUCOP_CTL &= ~FUCOP_CTL_mskCP0EN; -+} -+ -+static inline void grab_fpu(struct pt_regs *regs) -+{ -+ regs->NDS32_FUCOP_CTL |= FUCOP_CTL_mskCP0EN; -+} -+ -+static inline void enable_fpu(void) -+{ -+ SET_FUCOP_CTL(GET_FUCOP_CTL() | FUCOP_CTL_mskCP0EN); -+} -+ -+static inline void disable_fpu(void) -+{ -+ SET_FUCOP_CTL(GET_FUCOP_CTL() & ~FUCOP_CTL_mskCP0EN); -+} -+ -+static inline void lose_fpu(int save) -+{ -+ preempt_disable(); -+ if (test_tsk_fpu(task_pt_regs(current))) { -+ if (save) -+ { -+ save_fpu(current); -+# ifndef CONFIG_UNLAZY_FPU -+ last_task_used_math=NULL; -+# endif -+ } -+ release_fpu(task_pt_regs(current)); -+ } -+ preempt_enable(); -+} -+ -+static inline void own_fpu(int restore) -+{ -+ preempt_disable(); -+ if (!test_tsk_fpu(task_pt_regs(current))) { -+ if (restore) -+ { -+# ifdef CONFIG_UNLAZY_FPU -+ fpload(¤t->thread.fpu); -+# else -+ if((last_task_used_math!=NULL) -+ &&(last_task_used_math!=current)) -+ save_fpu(last_task_used_math); -+ fpload(¤t->thread.fpu); -+ last_task_used_math=current; -+#endif -+ } -+ grab_fpu(task_pt_regs(current)); -+ } -+ preempt_enable(); -+} -+# ifdef CONFIG_UNLAZY_FPU -+static inline void unlazy_fpu(struct task_struct *tsk) -+{ -+ preempt_disable(); -+ if (test_tsk_fpu(task_pt_regs(tsk))) -+ save_fpu(tsk); -+ preempt_enable(); -+} -+# endif /* CONFIG_UNLAZY_FPU */ -+static inline void clear_fpu(struct pt_regs *regs) -+{ -+ preempt_disable(); -+ if (test_tsk_fpu(regs)) { -+ release_fpu(regs); -+ } -+ preempt_enable(); -+} -+#endif /* CONFIG_FPU */ -+#endif /* __ASSEMBLY__ */ -+ -+#endif /* __ASM_NDS32_FPU_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ftpci.h linux-3.4.113/arch/nds32/include/asm/ftpci.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ftpci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ftpci.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,30 @@ -+/* -+ * linux/arch/nds32/include/asm/ftpci.h -+ * -+ * Faraday FTPCI010 PCI Bridge Device Driver Interface -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * ChangeLog -+ * -+ * Peter Liao 09/26/2005 Created, heavily modified from Faraday A320 platform code. -+ */ -+ -+#ifndef __FARADAY_PLATFORM_PCI_HEADER__ -+#define __FARADAY_PLATFORM_PCI_HEADER__ -+ -+ -+#define PCI_BRIDGE_DEVID 0x4321 -+#define PCI_BRIDGE_VENID 0x159b -+ -+extern int ftpci_probed; -+extern void ftpci_clear_irq(unsigned int irq); -+extern void ftpci_mask_irq(unsigned int irq); -+extern void ftpci_unmask_irq(unsigned int irq); -+extern int ftpci_get_irq(void); -+#endif /* __FARADAY_PLATFORM_PCI_HEADER__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ftrace.h linux-3.4.113/arch/nds32/include/asm/ftrace.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ftrace.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ftrace.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,17 @@ -+#ifndef _ASM_POWERPC_FTRACE -+#define _ASM_POWERPC_FTRACE -+ -+#ifdef CONFIG_FUNCTION_TRACER -+#define MCOUNT_ADDR ((long)(_mcount)) -+#define MCOUNT_INSN_SIZE 4 /* sizeof mcount call */ -+ -+#ifdef __ASSEMBLY__ -+ -+#else /* !__ASSEMBLY__ */ -+extern void _mcount(void); -+ -+#endif /* __ASSEMBLY__ */ -+ -+#endif -+ -+#endif /* _ASM_POWERPC_FTRACE */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/futex.h linux-3.4.113/arch/nds32/include/asm/futex.h ---- linux-3.4.113.orig/arch/nds32/include/asm/futex.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/futex.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/futex.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_FUTEX_H__ -+#define __NDS32_FUTEX_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/glue.h linux-3.4.113/arch/nds32/include/asm/glue.h ---- linux-3.4.113.orig/arch/nds32/include/asm/glue.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/glue.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,26 @@ -+/* -+ * linux/arch/nds32/include/asm/glue.h -+ * -+ * Copyright (C) 1997-1999 Russell King -+ * Copyright (C) 2000-2002 Deep Blue Solutions Ltd. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * This file provides the glue to stick the processor-specific bits -+ * into the kernel in an efficient manner. The idea is to use branches -+ * when we're only targetting one class of TLB, or indirect calls -+ * when we're targetting multiple classes of TLBs. -+ */ -+#ifdef __KERNEL__ -+ -+#ifdef __STDC__ -+#define ____glue(name,fn) name##fn -+#else -+#define ____glue(name,fn) name/**/fn -+#endif -+#define __glue(name,fn) ____glue(name,fn) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/gpio.h linux-3.4.113/arch/nds32/include/asm/gpio.h ---- linux-3.4.113.orig/arch/nds32/include/asm/gpio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/gpio.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,10 @@ -+#ifndef _ARCH_NDS32_GPIO_H -+#define _ARCH_NDS32_GPIO_H -+ -+#include -+#define gpio_get_value __gpio_get_value -+#define gpio_set_value __gpio_set_value -+#define gpio_cansleep __gpio_cansleep -+#define gpio_to_irq __gpio_to_irq -+ -+#endif /* _ARCH_NDS32_GPIO_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/hardirq.h linux-3.4.113/arch/nds32/include/asm/hardirq.h ---- linux-3.4.113.orig/arch/nds32/include/asm/hardirq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/hardirq.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * linux/arch/nds32/include/asm/hardirq.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+#ifndef __ASM_HARDIRQ_H -+#define __ASM_HARDIRQ_H -+ -+#include -+#include -+#include -+ -+typedef struct { -+ unsigned int __softirq_pending; -+} ____cacheline_aligned irq_cpustat_t; -+ -+#include /* Standard mappings for irq_cpustat_t above */ -+ -+#if NR_IRQS > 256 -+#define HARDIRQ_BITS 9 -+#else -+#define HARDIRQ_BITS 8 -+#endif -+ -+/* -+ * The hardirq mask has to be large enough to have space -+ * for potentially all IRQ sources in the system nesting -+ * on a single CPU: -+ */ -+#if (1 << HARDIRQ_BITS) < NR_IRQS -+# error HARDIRQ_BITS is too low! -+#endif -+ -+#define __ARCH_IRQ_EXIT_IRQS_DISABLED 1 -+ -+extern void ack_bad_irq(unsigned int irq); -+#endif /* __ASM_HARDIRQ_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/hardware.h linux-3.4.113/arch/nds32/include/asm/hardware.h ---- linux-3.4.113.orig/arch/nds32/include/asm/hardware.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/hardware.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,61 @@ -+/* -+ * linux/arch/nds32/include/asm/hardware.h -+ * -+ * Faraday Platform Independent Hardware Configuration -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/16/2005 Created. -+ * Peter Liao 10/04/2005 Modified for uClinux -+ * Harry Pan 11/02/2007 Added REGxx macros. -+ */ -+ -+#ifndef __FARADAY_PLATFORM_HARDWARE_HEADER__ -+#define __FARADAY_PLATFORM_HARDWARE_HEADER__ -+ -+#include -+ -+#ifndef PCIBIOS_MIN_IO -+/* the mini io address is 0x6000,that is IO will allocate from 0-0x6000 offset*/ -+#define PCIBIOS_MIN_IO 0x0 -+#endif -+ -+#ifndef PCIBIOS_MIN_MEM -+/* the mini MEM address is 0x100000,that is MEM will allocate from 0-0x100000 offset*/ -+#define PCIBIOS_MIN_MEM 0x0 -+#endif -+ -+#define pcibios_assign_all_busses() 1 -+ -+/* Pliauo add 5 to resolve __alloc_bootmem_core return NULL pointer in bootmem.c */ -+#if defined(CPU_MEM_PA_BASE) && defined(CPU_MEM_PA_SIZE) -+ #define PA_SDRAM_BASE (CPU_MEM_PA_BASE) -+#else -+ #define PA_SDRAM_BASE (0x00000000) -+#endif -+ -+/* -+ * Define a simple register accessing method by Harry@Nov.02.2007 -+ */ -+#define REG32(a) (*(volatile unsigned int *)(a)) -+#define REG16(a) (*(volatile unsigned short *)(a)) -+#define REG8(a) (*(volatile unsigned char *)(a)) -+ -+#endif /* __FARADAY_PLATFORM_HARDWARE_HEADER__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/highmem.h linux-3.4.113/arch/nds32/include/asm/highmem.h ---- linux-3.4.113.orig/arch/nds32/include/asm/highmem.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/highmem.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,61 @@ -+#ifndef _ASM_HIGHMEM_H -+#define _ASM_HIGHMEM_H -+ -+#include -+#include -+#include -+ -+/* -+ * Right now we initialize only a single pte table. It can be extended -+ * easily, subsequent pte tables have to be allocated in one physical -+ * chunk of RAM. -+ */ -+/* -+ * Ordering is (from lower to higher memory addresses): -+ * -+ * high_memory -+ * Persistent kmap area -+ * PKMAP_BASE -+ * fixed_addresses -+ * FIXADDR_START -+ * FIXADDR_TOP -+ * Vmalloc area -+ * VMALLOC_START -+ * VMALLOC_END -+ */ -+#define PKMAP_BASE ((FIXADDR_START - PGDIR_SIZE) & (PGDIR_MASK)) -+#define LAST_PKMAP PTRS_PER_PTE -+#define LAST_PKMAP_MASK (LAST_PKMAP - 1) -+#define PKMAP_NR(virt) (((virt) - (PKMAP_BASE)) >> PAGE_SHIFT) -+#define PKMAP_ADDR(nr) (PKMAP_BASE + ((nr) << PAGE_SHIFT)) -+#define kmap_prot PAGE_KERNEL -+ -+static inline void flush_cache_kmaps(void) -+{ -+ cpu_dcache_wbinval_all(); -+} -+ -+/* declarations for highmem.c */ -+extern unsigned long highstart_pfn, highend_pfn; -+ -+extern pte_t *pkmap_page_table; -+ -+extern void *kmap_high(struct page *page); -+extern void kunmap_high(struct page *page); -+ -+extern void kmap_init(void); -+ -+/* -+ * The following functions are already defined by -+ * when CONFIG_HIGHMEM is not set. -+ */ -+#ifdef CONFIG_HIGHMEM -+extern void *kmap(struct page *page); -+extern void kunmap(struct page *page); -+extern void *kmap_atomic(struct page *page); -+extern void __kunmap_atomic(void *kvaddr); -+extern void *kmap_atomic_pfn(unsigned long pfn); -+extern struct page *kmap_atomic_to_page(void *ptr); -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/hw_irq.h linux-3.4.113/arch/nds32/include/asm/hw_irq.h ---- linux-3.4.113.orig/arch/nds32/include/asm/hw_irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/hw_irq.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/hw_irq.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_HW_IRQ_H__ -+#define __NDS32_HW_IRQ_H__ -+ -+ -+#endif /* __NDS32_HW_IRQ_H__ */ -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/intc.h linux-3.4.113/arch/nds32/include/asm/intc.h ---- linux-3.4.113.orig/arch/nds32/include/asm/intc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/intc.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,45 @@ -+/* -+ * linux/arch/nds32/include/asm/intc.h -+ * -+ * Faraday FTINTC010 Interrupt Controller Device Driver Interface -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/14/2005 Created, heavily modified from Faraday CPE platform code. -+ */ -+ -+#ifndef __FARADAY_INTC_FTINTC010_HEADER__ -+#define __FARADAY_INTC_FTINTC010_HEADER__ -+ -+#define IRQ_SOURCE_REG 0 -+#define IRQ_MASK_REG 0x04 -+#define IRQ_CLEAR_REG 0x08 -+#define IRQ_MODE_REG 0x0c -+#define IRQ_LEVEL_REG 0x10 -+#define IRQ_STATUS_REG 0x14 -+ -+#define FIQ_SOURCE_REG 0x20 -+#define FIQ_MASK_REG 0x24 -+#define FIQ_CLEAR_REG 0x28 -+#define FIQ_MODE_REG 0x2c -+#define FIQ_LEVEL_REG 0x30 -+#define FIQ_STATUS_REG 0x34 -+ -+#endif /* __FARADAY_INTC_FTINTC010_HEADER__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ioctl.h linux-3.4.113/arch/nds32/include/asm/ioctl.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ioctl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ioctl.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/ioctl.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_IOCTL_H__ -+#define __NDS32_IOCTL_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ioctls.h linux-3.4.113/arch/nds32/include/asm/ioctls.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ioctls.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ioctls.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,13 @@ -+/* -+ * linux/arch/nds32/include/asm/ioctls.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_IOCTLS_H -+#define __ASM_NDS32_IOCTLS_H -+ -+#define FIOQSIZE 0x545E -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/io.h linux-3.4.113/arch/nds32/include/asm/io.h ---- linux-3.4.113.orig/arch/nds32/include/asm/io.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/io.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,343 @@ -+/* -+ * linux/arch/nds32/include/asm/io.h -+ * -+ * Copyright (C) 1996-2000 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Modifications: -+ * 16-Sep-1996 RMK Inlined the inx/outx functions & optimised for both -+ * constant addresses and variable addresses. -+ * 04-Dec-1997 RMK Moved a lot of this stuff to the new architecture -+ * specific IO header files. -+ * 27-Mar-1999 PJB Second parameter of memcpy_toio is const.. -+ * 04-Apr-1999 PJB Added check_signature. -+ * 12-Dec-1999 RMK More cleanups -+ * 18-Jun-2000 RMK Removed virt_to_* and friends definitions -+ * 05-Oct-2004 BJD Moved memory string functions to use void __iomem -+ */ -+#ifndef __ASM_NDS32_IO_H -+#define __ASM_NDS32_IO_H -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include -+ -+ -+/* -+ * ISA I/O bus memory addresses are 1:1 with the physical address. -+ */ -+#define isa_virt_to_bus virt_to_phys -+#define isa_page_to_bus page_to_phys -+#define isa_bus_to_virt phys_to_virt -+ -+/* -+ * Generic IO read/write. These perform native-endian accesses. Note -+ * that some architectures will want to re-define __raw_{read,write}w. -+ */ -+ -+#define __raw_writeb(v,a) (*(volatile unsigned char __force *)(a) = (v)) -+#define __raw_writew(v,a) (*(volatile unsigned short __force *)(a) = (v)) -+#define __raw_writel(v,a) (*(volatile unsigned int __force *)(a) = (v)) -+ -+#define __raw_readb(a) (*(volatile unsigned char __force *)(a)) -+#define __raw_readw(a) (*(volatile unsigned short __force *)(a)) -+#define __raw_readl(a) (*(volatile unsigned int __force *)(a)) -+ -+/* -+ * Bad read/write accesses... -+ */ -+extern void __readwrite_bug(const char *fn); -+ -+/* -+ * Now, pick up the machine-defined IO definitions -+ */ -+#ifndef __FARADAY_PLATFORM_IO_HEADER__ -+#define __FARADAY_PLATFORM_IO_HEADER__ -+ -+#include -+#include -+ -+#ifndef IO_SPACE_LIMIT -+#define IO_SPACE_LIMIT 0xffffffff -+#endif -+ -+#ifndef __io -+#define __io(a) ((void __iomem *)(a)) -+#endif -+#define IO_ADDRESS(a) __io(a) -+#ifndef __mem_pci -+#define __mem_pci(a) (a) -+#endif -+ -+#endif -+ -+#ifdef __io_pci -+#warning machine class uses buggy __io_pci -+#endif -+#if defined(__arch_putb) || defined(__arch_putw) || defined(__arch_putl) || \ -+ defined(__arch_getb) || defined(__arch_getw) || defined(__arch_getl) -+//-Tom for debug -+//#warning machine class uses old __arch_putw or __arch_getw -+#endif -+ -+/* -+ * IO port access primitives -+ * ------------------------- -+ * -+ * The ARM doesn't have special IO access instructions; all IO is memory -+ * mapped. Note that these are defined to perform little endian accesses -+ * only. Their primary purpose is to access PCI and ISA peripherals. -+ * -+ * Note that for a big endian machine, this implies that the following -+ * big endian mode connectivity is in place, as described by numerious -+ * ARM documents: -+ * -+ * PCI: D0-D7 D8-D15 D16-D23 D24-D31 -+ * ARM: D24-D31 D16-D23 D8-D15 D0-D7 -+ * -+ * The machine specific io.h include defines __io to translate an "IO" -+ * address to a memory address. -+ * -+ * Note that we prevent GCC re-ordering or caching values in expressions -+ * by introducing sequence points into the in*() definitions. Note that -+ * __raw_* do not guarantee this behaviour. -+ * -+ * The {in,out}[bwl] macros are for emulating x86-style PCI/ISA IO space. -+ */ -+#ifdef __io -+#ifdef __NDS32_EB__ -+#define inw(p) ({ unsigned int __v = be16_to_cpu(__raw_readw(__io(p))); __v; }) -+#define inl(p) ({ unsigned int __v = be32_to_cpu(__raw_readl(__io(p))); __v; }) -+#define outw(v,p) __raw_writew(cpu_to_be16(v),__io(p)) -+#define outl(v,p) __raw_writel(cpu_to_be32(v),__io(p)) -+#else -+#define inw(p) ({ unsigned int __v = le16_to_cpu(__raw_readw(__io(p))); __v; }) -+#define inl(p) ({ unsigned int __v = le32_to_cpu(__raw_readl(__io(p))); __v; }) -+#define outw(v,p) __raw_writew(cpu_to_le16(v),__io(p)) -+#define outl(v,p) __raw_writel(cpu_to_le32(v),__io(p)) -+#endif -+ -+#define inb(p) ({ unsigned int __v = __raw_readb(__io(p)); __v; }) -+#define outb(v,p) __raw_writeb(v,__io(p)) -+ -+#endif -+ -+#define outb_p(val,port) outb((val),(port)) -+#define outw_p(val,port) outw((val),(port)) -+#define outl_p(val,port) outl((val),(port)) -+#define inb_p(port) inb((port)) -+#define inw_p(port) inw((port)) -+#define inl_p(port) inl((port)) -+ -+/* -+ * String version of IO memory access ops: -+ */ -+extern void _memcpy_fromio(void *, const volatile void __iomem *, size_t); -+extern void _memcpy_toio(volatile void __iomem *, const void *, size_t); -+extern void _memset_io(volatile void __iomem *, int, size_t); -+ -+#define mmiowb() -+ -+/* -+ * Memory access primitives -+ * ------------------------ -+ * -+ * These perform PCI memory accesses via an ioremap region. They don't -+ * take an address as such, but a cookie. -+ * -+ * Again, this are defined to perform little endian accesses. See the -+ * IO port primitives for more information. -+ */ -+#ifdef __mem_pci -+#ifdef __NDS32_EB__ -+#define readw(c) ({ unsigned int __v = be16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) -+#define readl(c) ({ unsigned int __v = be32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) -+#define writew(v,c) __raw_writew(cpu_to_be16(v),__mem_pci(c)) -+#define writel(v,c) __raw_writel(cpu_to_be32(v),__mem_pci(c)) -+#else -+#define readw(c) ({ unsigned int __v = le16_to_cpu(__raw_readw(__mem_pci(c))); __v; }) -+#define readl(c) ({ unsigned int __v = le32_to_cpu(__raw_readl(__mem_pci(c))); __v; }) -+#define writew(v,c) __raw_writew(cpu_to_le16(v),__mem_pci(c)) -+#define writel(v,c) __raw_writel(cpu_to_le32(v),__mem_pci(c)) -+#endif -+ -+#define readb(c) ({ unsigned int __v = __raw_readb(__mem_pci(c)); __v; }) -+#define writeb(v,c) __raw_writeb(v,__mem_pci(c)) -+ -+#define readb_relaxed(addr) readb(addr) -+#define readw_relaxed(addr) readw(addr) -+#define readl_relaxed(addr) readl(addr) -+ -+#define memset_io(c,v,l) _memset_io(__mem_pci(c),(v),(l)) -+#define memcpy_fromio(a,c,l) _memcpy_fromio((a),__mem_pci(c),(l)) -+#define memcpy_toio(c,a,l) _memcpy_toio(__mem_pci(c),(a),(l)) -+ -+#define eth_io_copy_and_sum(s,c,l,b) \ -+ eth_copy_and_sum((s),__mem_pci(c),(l),(b)) -+ -+#elif !defined(readb) -+ -+#define readb(c) (__readwrite_bug("readb"),0) -+#define readw(c) (__readwrite_bug("readw"),0) -+#define readl(c) (__readwrite_bug("readl"),0) -+#define writeb(v,c) __readwrite_bug("writeb") -+#define writew(v,c) __readwrite_bug("writew") -+#define writel(v,c) __readwrite_bug("writel") -+ -+#define eth_io_copy_and_sum(s,c,l,b) __readwrite_bug("eth_io_copy_and_sum") -+ -+#endif /* __mem_pci */ -+ -+/* -+ * If this architecture has ISA IO, then define the isa_read/isa_write -+ * macros. -+ */ -+#ifdef __mem_isa -+ -+#define isa_readb(addr) __raw_readb(__mem_isa(addr)) -+#define isa_readw(addr) __raw_readw(__mem_isa(addr)) -+#define isa_readl(addr) __raw_readl(__mem_isa(addr)) -+#define isa_writeb(val,addr) __raw_writeb(val,__mem_isa(addr)) -+#define isa_writew(val,addr) __raw_writew(val,__mem_isa(addr)) -+#define isa_writel(val,addr) __raw_writel(val,__mem_isa(addr)) -+#define isa_memset_io(a,b,c) _memset_io(__mem_isa(a),(b),(c)) -+#define isa_memcpy_fromio(a,b,c) _memcpy_fromio((a),__mem_isa(b),(c)) -+#define isa_memcpy_toio(a,b,c) _memcpy_toio(__mem_isa((a)),(b),(c)) -+ -+#define isa_eth_io_copy_and_sum(a,b,c,d) \ -+ eth_copy_and_sum((a),__mem_isa(b),(c),(d)) -+ -+#else /* __mem_isa */ -+ -+#define isa_readb(addr) (__readwrite_bug("isa_readb"),0) -+#define isa_readw(addr) (__readwrite_bug("isa_readw"),0) -+#define isa_readl(addr) (__readwrite_bug("isa_readl"),0) -+#define isa_writeb(val,addr) __readwrite_bug("isa_writeb") -+#define isa_writew(val,addr) __readwrite_bug("isa_writew") -+#define isa_writel(val,addr) __readwrite_bug("isa_writel") -+#define isa_memset_io(a,b,c) __readwrite_bug("isa_memset_io") -+#define isa_memcpy_fromio(a,b,c) __readwrite_bug("isa_memcpy_fromio") -+#define isa_memcpy_toio(a,b,c) __readwrite_bug("isa_memcpy_toio") -+ -+#define isa_eth_io_copy_and_sum(a,b,c,d) \ -+ __readwrite_bug("isa_eth_io_copy_and_sum") -+ -+#endif /* __mem_isa */ -+ -+/* -+ * ioremap and friends. -+ * -+ * ioremap takes a PCI memory address, as specified in -+ * Documentation/IO-mapping.txt. -+ */ -+extern void __iomem * __ioremap(unsigned long, size_t, unsigned long, unsigned long); -+extern void __iounmap(void __iomem *addr); -+ -+#ifndef __arch_ioremap -+#define ioremap(cookie,size) __ioremap(cookie,size,0,1) -+#define ioremap_nocache(cookie,size) __ioremap(cookie,size,0,1) -+#define iounmap(cookie) __iounmap(cookie) -+#else -+#define ioremap(cookie,size) __arch_ioremap((cookie),(size),0,1) -+#define ioremap_nocache(cookie,size) __arch_ioremap((cookie),(size),0,1) -+#define iounmap(cookie) __arch_iounmap(cookie) -+#endif -+ -+/* -+ * can the hardware map this into one segment or not, given no other -+ * constraints. -+ */ -+#define BIOVEC_MERGEABLE(vec1, vec2) \ -+ ((bvec_to_phys((vec1)) + (vec1)->bv_len) == bvec_to_phys((vec2))) -+ -+/* -+ * Convert a physical pointer to a virtual kernel pointer for /dev/mem -+ * access -+ */ -+#define xlate_dev_mem_ptr(p) __va(p) -+ -+/* -+ * Convert a virtual cached pointer to an uncached pointer -+ */ -+#define xlate_dev_kmem_ptr(p) p -+static inline void readsb(const void __iomem *addr, void * data, int bytelen) -+{ -+ unsigned char *ptr = (unsigned char *)addr; -+ unsigned char *ptr2 = (unsigned char *)data; -+ while(bytelen) { -+ *ptr2 = *ptr; -+ ptr2++; -+ bytelen--; -+ } -+} -+ -+static inline void readsw(const void __iomem *addr, void * data, int wordlen) -+{ -+ unsigned short *ptr = (unsigned short *)addr; -+ unsigned short *ptr2 = (unsigned short *)data; -+ while(wordlen) { -+ *ptr2 = *ptr; -+ ptr2++; -+ wordlen--; -+ } -+} -+ -+static inline void readsl(const void __iomem *addr, void * data, int longlen) -+{ -+ unsigned int *ptr = (unsigned int *)addr; -+ unsigned int *ptr2 = (unsigned int *)data; -+ while(longlen) { -+ *ptr2 = *ptr; -+ ptr2++; -+ longlen--; -+ } -+} -+static inline void writesb(void __iomem *addr, const void * data, int bytelen) -+{ -+ unsigned char *ptr = (unsigned char *)addr; -+ unsigned char *ptr2 = (unsigned char *)data; -+ while(bytelen) { -+ *ptr = *ptr2; -+ ptr2++; -+ bytelen--; -+ } -+} -+static inline void writesw(void __iomem *addr, const void * data, int wordlen) -+{ -+ unsigned short *ptr = (unsigned short *)addr; -+ unsigned short *ptr2 = (unsigned short *)data; -+ while(wordlen) { -+ *ptr = *ptr2; -+ ptr2++; -+ wordlen--; -+ } -+} -+static inline void writesl(void __iomem *addr, const void * data, int longlen) -+{ -+ unsigned int *ptr = (unsigned int *)addr; -+ unsigned int *ptr2 = (unsigned int *)data; -+ while(longlen) { -+ *ptr = *ptr2; -+ ptr2++; -+ longlen--; -+ } -+} -+ -+ -+#define insb(p,d,l) BUG() -+#define insw(p,d,l) BUG() -+#define insl(p,d,l) BUG() -+#define outsb(p,d,l) BUG() -+#define outsw(p,d,l) BUG() -+#define outsl(p,d,l) BUG() -+ -+#endif /* __KERNEL__ */ -+#endif /* __ASM_NDS32_IO_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ipcbuf.h linux-3.4.113/arch/nds32/include/asm/ipcbuf.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ipcbuf.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ipcbuf.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,34 @@ -+/* -+ * linux/arch/nds32/include/asm/ipcbuf.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASMNDS32_IPCBUF_H -+#define __ASMNDS32_IPCBUF_H -+ -+/* -+ * The ipc64_perm structure for arm architecture. -+ * Note extra padding because this structure is passed back and forth -+ * between kernel and user space. -+ * -+ * Pad space is left for: -+ * - 32-bit mode_t and seq -+ * - 2 miscellaneous 32-bit values -+ */ -+ -+struct ipc64_perm -+{ -+ __kernel_key_t key; -+ __kernel_uid32_t uid; -+ __kernel_gid32_t gid; -+ __kernel_uid32_t cuid; -+ __kernel_gid32_t cgid; -+ __kernel_mode_t mode; -+ unsigned short __pad1; -+ unsigned short seq; -+ unsigned short __pad2; -+ unsigned long __unused1; -+ unsigned long __unused2; -+}; -+ -+#endif /* __ASMNDS32_IPCBUF_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/irqflags.h linux-3.4.113/arch/nds32/include/asm/irqflags.h ---- linux-3.4.113.orig/arch/nds32/include/asm/irqflags.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/irqflags.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,65 @@ -+/* -+ * linux/arch/nds32/include/asm/irqflags.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#include -+#include -+ -+#define arch_local_irq_disable() \ -+ GIE_DISABLE(); -+ -+#define arch_local_irq_enable() \ -+ GIE_ENABLE(); -+static inline unsigned long arch_local_irq_save(void) -+{ -+ unsigned long flags; -+ __asm__ __volatile__( -+ "mfsr %0, $PSW\n" -+ "andi %0, %0, #0x1\n" -+ "gie_disable\n" -+ : "=r" (flags) ); -+ return flags; -+} -+static inline unsigned long arch_local_save_flags(void) -+{ -+ unsigned long flags; -+ __asm__ __volatile__( -+ "mfsr %0, $PSW\n" -+ "andi %0, %0, #0x1" -+ : "=r" (flags) ); -+ return flags; -+} -+static inline void arch_local_irq_restore(unsigned long flags) -+{ -+ __asm__ __volatile__( -+ "beqz %0, 1f\n" -+ "gie_enable\n" -+ "1:" -+ :: "r" (flags) ); -+} -+static inline int arch_irqs_disabled_flags(unsigned long flags) -+{ -+ return !flags; -+} -+#if 0 -+#define raw_local_irq_save(x) \ -+ __asm__ __volatile__( \ -+ "mfsr %0, $PSW\n" \ -+ "andi %0, %0, #0x1\n" \ -+ "gie_disable\n" \ -+ : "=r" (x) ) -+#define raw_local_save_flags(x) \ -+ __asm__ __volatile__( \ -+ "mfsr %0, $PSW\n" \ -+ "andi %0, %0, #0x1" \ -+ : "=r" (x) ) -+#define raw_local_irq_restore(x) \ -+ __asm__ __volatile__( \ -+ "beqz %0, 1f\n" \ -+ "gie_enable\n" \ -+ "1:" \ -+ :: "r" (x) ) -+ -+#define raw_irqs_disabled_flags(x) !(x) -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/irq.h linux-3.4.113/arch/nds32/include/asm/irq.h ---- linux-3.4.113.orig/arch/nds32/include/asm/irq.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/irq.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,50 @@ -+/* -+ * linux/arch/nds32/include/asm/irq.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_IRQ_H -+#define __ASM_NDS32_IRQ_H -+ -+#include -+ -+#ifndef irq_canonicalize -+#define irq_canonicalize(i) (i) -+#endif -+ -+#ifndef NR_IRQS -+#define NR_IRQS 128 -+#endif -+ -+/* -+ * Use this value to indicate lack of interrupt -+ * capability -+ */ -+#ifndef NO_IRQ -+#define NO_IRQ ((unsigned int)(-1)) -+#endif -+ -+struct irqaction; -+ -+extern void disable_irq_nosync(unsigned int); -+extern void disable_irq(unsigned int); -+extern void enable_irq(unsigned int); -+ -+#define __IRQT_FALEDGE IRQ_TYPE_EDGE_FALLING -+#define __IRQT_RISEDGE IRQ_TYPE_EDGE_RISING -+#define __IRQT_LOWLVL IRQ_TYPE_LEVEL_LOW -+#define __IRQT_HIGHLVL IRQ_TYPE_LEVEL_HIGH -+ -+#define IRQT_NOEDGE (0) -+#define IRQT_RISING (__IRQT_RISEDGE) -+#define IRQT_FALLING (__IRQT_FALEDGE) -+#define IRQT_BOTHEDGE (__IRQT_RISEDGE|__IRQT_FALEDGE) -+#define IRQT_LOW (__IRQT_LOWLVL) -+#define IRQT_HIGH (__IRQT_HIGHLVL) -+#define IRQT_PROBE IRQ_TYPE_PROBE -+ -+struct irqaction; -+struct pt_regs; -+ -+#endif -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/irq_regs.h linux-3.4.113/arch/nds32/include/asm/irq_regs.h ---- linux-3.4.113.orig/arch/nds32/include/asm/irq_regs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/irq_regs.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,9 @@ -+/* -+ * linux/arch/nds32/include/asm/irq_regs.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_IRQ_REGS_H__ -+#define __NDS32_IRQ_REGS_H__ -+#include -+#endif /* __NDS32_IRQ_REGS_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/Kbuild linux-3.4.113/arch/nds32/include/asm/Kbuild ---- linux-3.4.113.orig/arch/nds32/include/asm/Kbuild 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/Kbuild 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,3 @@ -+include include/asm-generic/Kbuild.asm -+ -+header-y += pfm.h -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/kdebug.h linux-3.4.113/arch/nds32/include/asm/kdebug.h ---- linux-3.4.113.orig/arch/nds32/include/asm/kdebug.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/kdebug.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,14 @@ -+/* -+ * linux/arch/nds32/include/asm/kdebug.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_KDEBUG_H__ -+#define __NDS32_KDEBUG_H__ -+ -+enum die_val { -+ DIE_OOPS = 1, -+ DIE_DEBUG, -+}; -+ -+#endif /* __NDS32_KDEBUG_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/kexec.h linux-3.4.113/arch/nds32/include/asm/kexec.h ---- linux-3.4.113.orig/arch/nds32/include/asm/kexec.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/kexec.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,31 @@ -+#ifndef _NDS32_KEXEC_H -+#define _NDS32_KEXEC_H -+ -+#ifdef CONFIG_KEXEC -+ -+/* Maximum physical address we can use pages from */ -+#define KEXEC_SOURCE_MEMORY_LIMIT (-1UL) -+/* Maximum address we can reach in physical address mode */ -+#define KEXEC_DESTINATION_MEMORY_LIMIT (-1UL) -+/* Maximum address we can use for the control code buffer */ -+#define KEXEC_CONTROL_MEMORY_LIMIT (-1UL) -+ -+#define KEXEC_CONTROL_PAGE_SIZE 4096 -+ -+#define KEXEC_ARCH KEXEC_ARCH_NDS32 -+ -+#define KEXEC_NDS32_ATAGS_OFFSET 0x1000 -+#define KEXEC_NDS32_ZIMAGE_OFFSET 0x500000 -+ -+#ifndef __ASSEMBLY__ -+ -+struct kimage; -+/* Provide a dummy definition to avoid build failures. */ -+static inline void crash_setup_regs(struct pt_regs *newregs, -+ struct pt_regs *oldregs) { } -+ -+#endif /* __ASSEMBLY__ */ -+ -+#endif /* CONFIG_KEXEC */ -+ -+#endif /* _NDS32_KEXEC_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/kgdb.h linux-3.4.113/arch/nds32/include/asm/kgdb.h ---- linux-3.4.113.orig/arch/nds32/include/asm/kgdb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/kgdb.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,90 @@ -+/* ============================================================================ -+ * -+ * linux/arch/nds32/include/asm/kgdb.h -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for NDS32 KGDB support. -+ * -+ * Author: Harry Pan -+ * -+ * Revision History: -+ * -+ * Jul.14.2007 Initial ported by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#ifndef __ASM_NDS32_KGDB_H__ -+#define __ASM_NDS32_KGDB_H__ -+ -+#include -+ -+#define BREAK_INSTR_SIZE 2 -+#define CACHE_FLUSH_IS_SAFE 1 -+ -+#ifndef __ASSEMBLY__ -+ -+/* -+ * Define numbers of registers we have in NDS32 arch -+ */ -+#define NDS32_NUM_GR 32 // general registers. -+#define NDS32_NUM_SPR 5 // special registers. (PC, D0, D1) -+#define NDS32_NUM_CR 6 // ctrl registers. -+#define NDS32_NUM_IR 16 // interruption registers. -+#define NDS32_NUM_MR 11 // MMU registers. -+#define NDS32_NUM_DR 48 // debug registers. -+#define NDS32_NUM_PFR 4 // performance monitoring registers. -+#define NDS32_NUM_DMAR 11 // local memory DMA registers -+#define NDS32_NUM_RACR 1 // resource access control registers. -+#define NDS32_NUM_IDR 2 // implementation dependent registers. -+#define NDS32_NUM_SR (NDS32_NUM_CR + NDS32_NUM_IR + NDS32_NUM_MR + \ -+ NDS32_NUM_DR + NDS32_NUM_PFR + NDS32_NUM_DMAR + \ -+ NDS32_NUM_RACR + NDS32_NUM_IDR) -+#define NDS32_NUM_REGS (NDS32_NUM_GR + NDS32_NUM_SPR + NDS32_NUM_SR) -+ -+#define KGDB_MAX_NO_CPUS 1 -+#define BUFMAX 2048 -+#define NUMREGBYTES (NDS32_NUM_REGS << 2) -+ -+/* -+ * NDS32 virtual registers layout for GDB. -+ */ -+enum nds32_regnum -+{ -+ NDS32_R0_REGNUM = 0, // first integer-like argument. -+ NDS32_R5_REGNUM = 5, // last integer-like argument. -+ NDS32_FP_REGNUM = 28, // frame register -+ NDS32_LP_REGNUM = 30, // link pointer -+ NDS32_SP_REGNUM = 31, // address of stack top. -+ NDS32_PC_REGNUM = 32, -+ NDS32_D0LO_REGNUM = 33, -+ NDS32_D0HI_REGNUM = 34, -+ NDS32_D1LO_REGNUM = 35, -+ NDS32_D1HI_REGNUM = 36, -+ NDS32_CR0_REGNUM = 37, -+ NDS32_IR0_REGNUM = (NDS32_CR0_REGNUM + NDS32_NUM_CR), -+ NDS32_MR0_REGNUM = (NDS32_IR0_REGNUM + NDS32_NUM_IR), -+ NDS32_DR0_REGNUM = (NDS32_MR0_REGNUM + NDS32_NUM_MR), -+ NDS32_PFR0_REGNUM = (NDS32_DR0_REGNUM + NDS32_NUM_DR), -+ NDS32_DMAR0_REGNUM = (NDS32_PFR0_REGNUM + NDS32_NUM_PFR), -+ NDS32_RACR0_REGNUM = (NDS32_DMAR0_REGNUM + NDS32_NUM_DMAR), -+ NDS32_IDR0_REGNUM = (NDS32_RACR0_REGNUM + NDS32_NUM_RACR), -+ /* nds32 calling convention. */ -+ NDS32_ARG0_REGNUM = NDS32_R0_REGNUM, -+ NDS32_ARGN_REGNUM = NDS32_R5_REGNUM, -+ NDS32_RET_REGNUM = NDS32_R0_REGNUM, -+}; -+ -+static inline void arch_kgdb_breakpoint(void) -+{ -+ asm __volatile__ ( "break 0x1ff\n" ); -+} -+ -+#endif /* !__ASSEMBLY__ */ -+#endif /* __ASM_NDS32_KGDB_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/kmap_types.h linux-3.4.113/arch/nds32/include/asm/kmap_types.h ---- linux-3.4.113.orig/arch/nds32/include/asm/kmap_types.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/kmap_types.h 2016-12-01 20:59:24.336612134 +0100 -@@ -0,0 +1,29 @@ -+/* -+ * linux/arch/nds32/include/asm/kmap-types.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_KMAP_TYPES_H -+#define __NDS32_KMAP_TYPES_H -+ -+/* -+ * This is the "bare minimum". AIO seems to require this. -+ */ -+enum km_type { -+ KM_BOUNCE_READ, -+ KM_SKB_SUNRPC_DATA, -+ KM_SKB_DATA_SOFTIRQ, -+ KM_USER0, -+ KM_USER1, -+ KM_BIO_SRC_IRQ, -+ KM_BIO_DST_IRQ, -+ KM_PTE0, -+ KM_PTE1, -+ KM_IRQ0, -+ KM_IRQ1, -+ KM_SOFTIRQ0, -+ KM_SOFTIRQ1, -+ KM_TYPE_NR -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/kprobes.h linux-3.4.113/arch/nds32/include/asm/kprobes.h ---- linux-3.4.113.orig/arch/nds32/include/asm/kprobes.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/kprobes.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,86 @@ -+#ifndef _ASM_ANDES_KPROBES_H -+#define _ASM_ANDES_KPROBES_H -+/* -+ * Kernel Probes (KProbes) -+ * -+ * 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. -+ * -+ * Copyright (C) IBM Corporation, 2002, 2004 -+ * -+ * See arch/x86/kernel/kprobes.c for x86 kprobes history. -+ */ -+#include -+#include -+#include -+ -+#define __ARCH_WANT_KPROBES_INSN_SLOT -+ -+struct pt_regs; -+struct kprobe; -+ -+typedef unsigned short kprobe_opcode_t; -+ -+#define MAX_INSN_SIZE 2 -+#define MAX_STACK_SIZE 64 -+#define MIN_STACK_SIZE(ADDR) \ -+ (((MAX_STACK_SIZE) < (((unsigned long)current_thread_info()) + \ -+ THREAD_SIZE - (unsigned long)(ADDR))) \ -+ ? (MAX_STACK_SIZE) \ -+ : (((unsigned long)current_thread_info()) + \ -+ THREAD_SIZE - (unsigned long)(ADDR))) -+#define regs_return_value(regs) ((regs)->NDS32_r0) -+#define flush_insn_slot(p) do { } while (0) -+#define kretprobe_blacklist_size 0 -+ -+void arch_remove_kprobe(struct kprobe *p); -+void kretprobe_trampoline(void); -+ -+/* Architecture specific copy of original instruction*/ -+struct arch_specific_insn { -+ /* copy of the original instruction */ -+ kprobe_opcode_t *insn; -+ /* -+ * boostable = -1: This instruction type is not boostable. -+ * boostable = 0: This instruction type is boostable. -+ * boostable = 1: This instruction has been boosted: we have -+ * added a relative jump after the instruction copy in insn, -+ * so no single-step and fixup are needed (unless there's -+ * a post_handler or break_handler). -+ */ -+ int boostable; -+}; -+ -+struct prev_kprobe { -+ struct kprobe *kp; -+ unsigned long status; -+ unsigned long old_flags; -+ unsigned long saved_flags; -+}; -+ -+/* per-cpu kprobe control block */ -+struct kprobe_ctlblk { -+ unsigned long kprobe_status; -+ unsigned long kprobe_old_flags; -+ unsigned long kprobe_saved_flags; -+ unsigned long *jprobe_saved_sp; -+ struct pt_regs jprobe_saved_regs; -+ kprobe_opcode_t jprobes_stack[MAX_STACK_SIZE]; -+ struct prev_kprobe prev_kprobe; -+}; -+ -+extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr); -+extern int kprobe_exceptions_notify(struct notifier_block *self, -+ unsigned long val, void *data); -+#endif /* _ASM_ANDES_KPROBES_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/kvm.h linux-3.4.113/arch/nds32/include/asm/kvm.h ---- linux-3.4.113.orig/arch/nds32/include/asm/kvm.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/kvm.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,9 @@ -+/* -+ * linux/arch/nds32/include/asm/kvm.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_KVM_H__ -+#define __NDS32_KVM_H__ -+ -+#endif /* __NDS32_KVM_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/l2_cache.h linux-3.4.113/arch/nds32/include/asm/l2_cache.h ---- linux-3.4.113.orig/arch/nds32/include/asm/l2_cache.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/l2_cache.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,134 @@ -+/* -+ * linux/arch/nds32/include/asm/l2_cache.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef L2_CACHE_H -+#define L2_CACHE_H -+ -+// CCTL_CMD_OP -+#define L2_CA_CONF_OFF 0x0 -+#define L2_IF_CONF_OFF 0x4 -+#define L2CC_SETUP_OFF 0x8 -+#define L2CC_PROT_OFF 0xC -+#define L2CC_CTRL_OFF 0x10 -+#define L2_INT_EN_OFF 0x20 -+#define L2_STA_OFF 0x24 -+#define RDERR_ADDR_OFF 0x28 -+#define WRERR_ADDR_OFF 0x2c -+#define EVDPTERR_ADDR_OFF 0x30 -+#define IMPL3ERR_ADDR_OFF 0x34 -+#define L2_CNT0_CTRL_OFF 0x40 -+#define L2_EVNT_CNT0_OFF 0x44 -+#define L2_CNT1_CTRL_OFF 0x48 -+#define L2_EVNT_CNT1_OFF 0x4c -+#define L2_CCTL_CMD_OFF 0x60 -+#define L2_CCTL_STATUS_OFF 0x64 -+#define L2_LINE_TAG_OFF 0x68 -+#define L2_LINE_DPT_OFF 0x70 -+ -+#define CCTL_CMD_L2_IX_INVAL 0x0 -+#define CCTL_CMD_L2_PA_INVAL 0x1 -+#define CCTL_CMD_L2_IX_WB 0x2 -+#define CCTL_CMD_L2_PA_WB 0x3 -+#define CCTL_CMD_L2_PA_WBINVAL 0x5 -+#define CCTL_CMD_L2_SYNC 0xa -+// CCTL_CMD_TYPE -+#define CCTL_SINGLE_CMD 0 -+#define CCTL_BLOCK_CMD 0x10 -+#define CCTL_ALL_CMD 0x10 -+ -+/****************************************************************************** -+ * L2_CA_CONF (Cache architecture configuration) -+ *****************************************************************************/ -+#define L2_CA_CONF_offL2SET 0 -+#define L2_CA_CONF_offL2WAY 4 -+#define L2_CA_CONF_offL2CLSZ 8 -+#define L2_CA_CONF_offL2DW 11 -+#define L2_CA_CONF_offL2PT 14 -+#define L2_CA_CONF_offL2VER 16 -+ -+#define L2_CA_CONF_mskL2SET (0xFUL << L2_CA_CONF_offL2SET) -+#define L2_CA_CONF_mskL2WAY (0xFUL << L2_CA_CONF_offL2WAY) -+#define L2_CA_CONF_mskL2CLSZ (0x7UL << L2_CA_CONF_offL2CLSZ) -+#define L2_CA_CONF_mskL2DW (0x7UL << L2_CA_CONF_offL2DW) -+#define L2_CA_CONF_mskL2PT (0x3UL << L2_CA_CONF_offL2PT) -+#define L2_CA_CONF_mskL2VER (0xFFFFUL << L2_CA_CONF_offL2VER) -+ -+/****************************************************************************** -+ * L2CC_SETUP (L2CC Setup register) -+ *****************************************************************************/ -+#define L2CC_SETUP_offPART 0 -+#define L2CC_SETUP_mskPART (0x3UL << L2CC_SETUP_offPART) -+#define L2CC_SETUP_offDDLATC 4 -+#define L2CC_SETUP_mskDDLATC (0x3UL << L2CC_SETUP_offDDLATC) -+#define L2CC_SETUP_offTDLATC 8 -+#define L2CC_SETUP_mskTDLATC (0x3UL << L2CC_SETUP_offTDLATC) -+ -+/****************************************************************************** -+ * L2CC_PROT (L2CC Protect register) -+ *****************************************************************************/ -+#define L2CC_PROT_offMRWEN 31 -+#define L2CC_PROT_mskMRWEN (0x1UL << L2CC_PROT_offMRWEN) -+//TODO finish this table -+// -+/****************************************************************************** -+ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n) -+ *****************************************************************************/ -+#define L2CC_CTRL_offEN 31 -+#define L2CC_CTRL_mskEN (0x1UL << L2CC_CTRL_offEN) -+ -+/****************************************************************************** -+ * L2_CCTL_STATUS_Mn (The L2CCTL command working status for Master n) -+ *****************************************************************************/ -+#define L2_CCTL_STATUS_offCMD_COMP 31 -+#define L2_CCTL_STATUS_mskCMD_COMP (0x1 << L2_CCTL_STATUS_offCMD_COMP) -+//TODO finish this table -+ -+#ifndef __ASSEMBLY__ -+ -+#include -+#include -+#include -+ -+#define L2C_R_REG(offset) inl(L2CC_VA_BASE + offset) -+#define L2C_W_REG(offset, value) outl(value, L2CC_VA_BASE + offset) -+ -+#define L2_CMD_RDY() \ -+ do{;}while((L2C_R_REG(L2_CCTL_STATUS_OFF) & L2_CCTL_STATUS_mskCMD_COMP) == 0) -+ -+static inline unsigned long L2_CACHE_SET(void){ -+ return 64 << ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> L2_CA_CONF_offL2SET); -+} -+ -+static inline unsigned long L2_CACHE_WAY(void){ -+ return 1 + ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> L2_CA_CONF_offL2WAY); -+} -+ -+static inline unsigned long L2_CACHE_LINE_SIZE(void){ -+ -+ return 4 << ( ( L2C_R_REG(L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> L2_CA_CONF_offL2CLSZ); -+} -+ -+static inline unsigned long GET_L2CC_CTRL_CPU(unsigned long cpu){ -+ if(cpu == smp_processor_id()) -+ return L2C_R_REG(L2CC_CTRL_OFF); -+ return L2C_R_REG(L2CC_CTRL_OFF+(cpu<<8)); -+} -+ -+static inline void SET_L2CC_CTRL_CPU(unsigned long cpu , unsigned long val){ -+ if(cpu == smp_processor_id()) -+ L2C_W_REG(L2CC_CTRL_OFF,val); -+ else -+ L2C_W_REG(L2CC_CTRL_OFF+(cpu<<8),val); -+} -+ -+static inline unsigned long GET_L2CC_STATUS_CPU(unsigned long cpu){ -+ if(cpu == smp_processor_id()) -+ return L2C_R_REG(L2_CCTL_STATUS_OFF); -+ return L2C_R_REG(L2_CCTL_STATUS_OFF+(cpu<<8)); -+} -+ -+#endif -+ -+#endif //L2_CACHE_H -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/leds.h linux-3.4.113/arch/nds32/include/asm/leds.h ---- linux-3.4.113.orig/arch/nds32/include/asm/leds.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/leds.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,51 @@ -+/* -+ * linux/arch/nds32/include/asm/leds.h -+ * -+ * Copyright (C) 1998 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Event-driven interface for LEDs on machines -+ * Added led_start and led_stop- Alex Holden, 28th Dec 1998. -+ */ -+#ifndef ASM_NDS32_LEDS_H -+#define ASM_NDS32_LEDS_H -+ -+ -+typedef enum { -+ led_idle_start, -+ led_idle_end, -+ led_timer, -+ led_start, -+ led_stop, -+ led_claim, /* override idle & timer leds */ -+ led_release, /* restore idle & timer leds */ -+ led_start_timer_mode, -+ led_stop_timer_mode, -+ led_green_on, -+ led_green_off, -+ led_amber_on, -+ led_amber_off, -+ led_red_on, -+ led_red_off, -+ led_blue_on, -+ led_blue_off, -+ /* -+ * I want this between led_timer and led_start, but -+ * someone has decided to export this to user space -+ */ -+ led_halted -+} led_event_t; -+ -+/* Use this routine to handle LEDs */ -+ -+#ifdef CONFIG_LEDS -+extern void (*leds_event)(led_event_t); -+#else -+#define leds_event(e) -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/limits.h linux-3.4.113/arch/nds32/include/asm/limits.h ---- linux-3.4.113.orig/arch/nds32/include/asm/limits.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/limits.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,16 @@ -+/* -+ * linux/arch/nds32/include/asm/limits.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_PIPE_H -+#define __ASM_PIPE_H -+ -+#ifndef PAGE_SIZE -+#include -+#endif -+ -+#define PIPE_BUF PAGE_SIZE -+ -+#endif -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/linkage.h linux-3.4.113/arch/nds32/include/asm/linkage.h ---- linux-3.4.113.orig/arch/nds32/include/asm/linkage.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/linkage.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,12 @@ -+/* -+ * linux/arch/nds32/include/asm/linkage.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_LINKAGE_H__ -+#define __NDS32_LINKAGE_H__ -+ -+#define __ALIGN .align 2 -+#define __ALIGN_STR ".align 2" -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/local.h linux-3.4.113/arch/nds32/include/asm/local.h ---- linux-3.4.113.orig/arch/nds32/include/asm/local.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/local.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/local.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_LOCAL_H__ -+#define __NDS32_LOCAL_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/arch.h linux-3.4.113/arch/nds32/include/asm/mach/arch.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/arch.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/arch.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,86 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/arch.h -+ * -+ * Copyright (C) 2000 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#ifndef __ASSEMBLY__ -+ -+struct tag; -+struct meminfo; -+struct sys_timer; -+ -+struct machine_desc { -+ /* -+ * Note! The first four elements are used -+ * by assembler code in head-armv.S -+ */ -+ unsigned int nr; /* architecture number */ -+ -+ const char *name; /* architecture name */ -+ unsigned int param_offset; /* parameter page */ -+ -+ unsigned int video_start; /* start of video RAM */ -+ unsigned int video_end; /* end of video RAM */ -+ -+ unsigned int reserve_lp0 :1; /* never has lp0 */ -+ unsigned int reserve_lp1 :1; /* never has lp1 */ -+ unsigned int reserve_lp2 :1; /* never has lp2 */ -+ unsigned int soft_reboot :1; /* soft reboot */ -+ void (*fixup)(struct machine_desc *, -+ struct tag *, char **, -+ struct meminfo *); -+ void (*map_io)(void);/* IO mapping function */ -+ void (*init_irq)(void); -+ struct sys_timer *timer; /* system tick timer */ -+ void (*init_machine)(void); -+}; -+ -+/* -+ * * Current machine - only accessible during boot. -+ * */ -+extern struct machine_desc *machine_desc; -+ -+/* -+ * Set of macros to define architecture features. This is built into -+ * a table by the linker. -+ */ -+#define MACHINE_START(_type,_name) \ -+const struct machine_desc __mach_desc_##_type \ -+ __attribute__((__section__(".arch.info"))) = { \ -+ .nr = MACH_TYPE_##_type, \ -+ .name = _name, -+ -+#define MAINTAINER(n) -+ -+#define BOOT_PARAMS(_params) \ -+ .param_offset = _params, -+ -+#define VIDEO(_start,_end) \ -+ .video_start = _start, \ -+ .video_end = _end, -+ -+#define DISABLE_PARPORT(_n) \ -+ .reserve_lp##_n = 1, -+ -+#define SOFT_REBOOT \ -+ .soft_reboot = 1, -+ -+#define MAPIO(_func) \ -+ .map_io = _func, -+ -+#define INITIRQ(_func) \ -+ .init_irq = _func, -+ -+#define INIT_MACHINE(_func) \ -+ .init_machine = _func, -+ -+#define MACHINE_END \ -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/dma.h linux-3.4.113/arch/nds32/include/asm/mach/dma.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/dma.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/dma.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,56 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/dma.h -+ * -+ * Copyright (C) 1998-2000 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * This header file describes the interface between the generic DMA handler -+ * (dma.c) and the architecture-specific DMA backends (dma-*.c) -+ */ -+ -+struct dma_struct; -+typedef struct dma_struct dma_t; -+ -+struct dma_ops { -+ int (*request)(dmach_t, dma_t *); /* optional */ -+ void (*free)(dmach_t, dma_t *); /* optional */ -+ void (*enable)(dmach_t, dma_t *); /* mandatory */ -+ void (*disable)(dmach_t, dma_t *); /* mandatory */ -+ int (*residue)(dmach_t, dma_t *); /* optional */ -+ int (*setspeed)(dmach_t, dma_t *, int); /* optional */ -+ char *type; -+}; -+ -+struct dma_struct { -+ struct scatterlist buf; /* single DMA */ -+ int sgcount; /* number of DMA SG */ -+ struct scatterlist *sg; /* DMA Scatter-Gather List */ -+ -+ unsigned int active:1; /* Transfer active */ -+ unsigned int invalid:1; /* Address/Count changed */ -+ unsigned int using_sg:1; /* using scatter list? */ -+ dmamode_t dma_mode; /* DMA mode */ -+ int speed; /* DMA speed */ -+ -+ unsigned int lock; /* Device is allocated */ -+ const char *device_id; /* Device name */ -+ -+ unsigned int dma_base; /* Controller base address */ -+ int dma_irq; /* Controller IRQ */ -+ struct scatterlist cur_sg; /* Current controller buffer */ -+ unsigned int state; -+ -+ struct dma_ops *d_ops; -+}; -+ -+/* Prototype: void arch_dma_init(dma) -+ * Purpose : Initialise architecture specific DMA -+ * Params : dma - pointer to array of DMA structures -+ */ -+extern void arch_dma_init(dma_t *dma); -+ -+extern void isa_init_dma(dma_t *dma); -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/flash.h linux-3.4.113/arch/nds32/include/asm/mach/flash.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/flash.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/flash.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,35 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/flash.h -+ * -+ * Copyright (C) 2003 Russell King, All Rights Reserved. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef ASMNDS32_MACH_FLASH_H -+#define ASMNDS32_MACH_FLASH_H -+ -+struct mtd_partition; -+ -+/* -+ * map_name: the map probe function name -+ * width: width of mapped device -+ * init: method called at driver/device initialisation -+ * exit: method called at driver/device removal -+ * set_vpp: method called to enable or disable VPP -+ * parts: optional array of mtd_partitions for static partitioning -+ * nr_parts: number of mtd_partitions for static partitoning -+ */ -+struct flash_platform_data { -+ const char *map_name; -+ unsigned int width; -+ int (*init)(void); -+ void (*exit)(void); -+ void (*set_vpp)(int on); -+ struct mtd_partition *parts; -+ unsigned int nr_parts; -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/irda.h linux-3.4.113/arch/nds32/include/asm/mach/irda.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/irda.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/irda.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,21 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/irda.h -+ * -+ * Copyright (C) 2004 Russell King. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_NDS32_MACH_IRDA_H -+#define __ASM_NDS32_MACH_IRDA_H -+ -+struct irda_platform_data { -+ int (*startup)(struct device *); -+ void (*shutdown)(struct device *); -+ int (*set_power)(struct device *, unsigned int state); -+ void (*set_speed)(struct device *, unsigned int speed); -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/map.h linux-3.4.113/arch/nds32/include/asm/mach/map.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/map.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/map.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,37 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/map.h -+ * -+ * Copyright (C) 1999-2000 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Page table mapping constructs and function prototypes -+ */ -+struct map_desc { -+ unsigned long virtual; -+ unsigned long physical; -+ unsigned long length; -+ unsigned int type; -+}; -+ -+struct meminfo; -+ -+#define MT_DEVICE_NCB MT_DEVICE -+#define MT_DEVICE_NCNB MT_DEVICE -+#define MT_DEVICE 0 -+#define MT_CACHECLEAN 1 -+#define MT_MINICLEAN 2 -+#define MT_CACHE_L1 3 -+#define MT_UXKRWX_V1 4 -+#define MT_UXKRWX_V2 5 -+#define MT_MEMORY 6 -+#define MT_ROM 7 -+#define MT_ILM 8 -+#define MT_DLM 9 -+ -+extern void create_memmap_holes(struct meminfo *); -+extern void iotable_init(struct map_desc *, int); -+extern void setup_io_desc(void); -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/mmc.h linux-3.4.113/arch/nds32/include/asm/mach/mmc.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/mmc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/mmc.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,16 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/mmc.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+#ifndef ASMNDS32_MACH_MMC_H -+#define ASMNDS32_MACH_MMC_H -+ -+#include -+ -+struct mmc_platform_data { -+ unsigned int ocr_mask; /* available voltages */ -+ u32 (*translate_vdd)(struct device *, unsigned int); -+ unsigned int (*status)(struct device *); -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/pci.h linux-3.4.113/arch/nds32/include/asm/mach/pci.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/pci.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,76 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/pci.h -+ * -+ * Copyright (C) 2000 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ */ -+ -+struct pci_sys_data; -+struct pci_bus; -+ -+struct hw_pci { -+ struct list_head buses; -+ int nr_controllers; -+ int (*setup)(int nr, struct pci_sys_data *); -+ struct pci_bus *(*scan)(int nr, struct pci_sys_data *); -+ void (*preinit)(void); -+ void (*postinit)(void); -+ u8 (*swizzle)(struct pci_dev *dev, u8 *pin); -+ int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); -+}; -+ -+/* -+ * Per-controller structure -+ */ -+struct pci_sys_data { -+ struct list_head node; -+ int busnr; /* primary bus number */ -+ unsigned long mem_offset; /* bus->cpu memory mapping offset */ -+ unsigned long io_offset; /* bus->cpu IO mapping offset */ -+ struct pci_bus *bus; /* PCI bus */ -+ struct resource *resource[3]; /* Primary PCI bus resources */ -+ /* Bridge swizzling */ -+ u8 (*swizzle)(struct pci_dev *, u8 *); -+ /* IRQ mapping */ -+ int (*map_irq)(struct pci_dev *, u8, u8); -+ struct hw_pci *hw; -+}; -+ -+/* -+ * This is the standard PCI-PCI bridge swizzling algorithm. -+ */ -+u8 pci_std_swizzle(struct pci_dev *dev, u8 *pinp); -+ -+/* -+ * Call this with your hw_pci struct to initialise the PCI system. -+ */ -+void pci_common_init(struct hw_pci *); -+ -+/* -+ * PCI controllers -+ */ -+extern int iop321_setup(int nr, struct pci_sys_data *); -+extern struct pci_bus *iop321_scan_bus(int nr, struct pci_sys_data *); -+extern void iop321_init(void); -+ -+extern int iop331_setup(int nr, struct pci_sys_data *); -+extern struct pci_bus *iop331_scan_bus(int nr, struct pci_sys_data *); -+extern void iop331_init(void); -+ -+extern int dc21285_setup(int nr, struct pci_sys_data *); -+extern struct pci_bus *dc21285_scan_bus(int nr, struct pci_sys_data *); -+extern void dc21285_preinit(void); -+extern void dc21285_postinit(void); -+ -+extern int via82c505_setup(int nr, struct pci_sys_data *); -+extern struct pci_bus *via82c505_scan_bus(int nr, struct pci_sys_data *); -+extern void via82c505_init(void *sysdata); -+ -+extern int pci_v3_setup(int nr, struct pci_sys_data *); -+extern struct pci_bus *pci_v3_scan_bus(int nr, struct pci_sys_data *); -+extern void pci_v3_preinit(void); -+extern void pci_v3_postinit(void); -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/serial_sa1100.h linux-3.4.113/arch/nds32/include/asm/mach/serial_sa1100.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/serial_sa1100.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/serial_sa1100.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,31 @@ -+/* -+ * linux/include/asm-arm/mach/serial_sa1100.h -+ * -+ * Author: Nicolas Pitre -+ * -+ * Moved to include/asm-arm/mach and changed lots, Russell King -+ * -+ * Low level machine dependent UART functions. -+ */ -+ -+struct uart_port; -+struct uart_info; -+ -+/* -+ * This is a temporary structure for registering these -+ * functions; it is intended to be discarded after boot. -+ */ -+struct sa1100_port_fns { -+ void (*set_mctrl)(struct uart_port *, u_int); -+ u_int (*get_mctrl)(struct uart_port *); -+ void (*pm)(struct uart_port *, u_int, u_int); -+ int (*set_wake)(struct uart_port *, u_int); -+}; -+ -+#ifdef CONFIG_SERIAL_SA1100 -+void sa1100_register_uart_fns(struct sa1100_port_fns *fns); -+void sa1100_register_uart(int idx, int port); -+#else -+#define sa1100_register_uart_fns(fns) do { } while (0) -+#define sa1100_register_uart(idx,port) do { } while (0) -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach/time.h linux-3.4.113/arch/nds32/include/asm/mach/time.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach/time.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach/time.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,62 @@ -+/* -+ * linux/arch/nds32/include/asm/mach/time.h -+ * -+ * Copyright (C) 2004 MontaVista Software, Inc. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_NDS32_MACH_TIME_H -+#define __ASM_NDS32_MACH_TIME_H -+ -+//#include -+ -+/* -+ * This is our kernel timer structure. -+ * -+ * - init -+ * Initialise the kernels jiffy timer source, claim interrupt -+ * using setup_irq. This is called early on during initialisation -+ * while interrupts are still disabled on the local CPU. -+ * - suspend -+ * Suspend the kernel jiffy timer source, if necessary. This -+ * is called with interrupts disabled, after all normal devices -+ * have been suspended. If no action is required, set this to -+ * NULL. -+ * - resume -+ * Resume the kernel jiffy timer source, if necessary. This -+ * is called with interrupts disabled before any normal devices -+ * are resumed. If no action is required, set this to NULL. -+ * - offset -+ * Return the timer offset in microseconds since the last timer -+ * interrupt. Note: this must take account of any unprocessed -+ * timer interrupt which may be pending. -+ */ -+ -+/* + Tom from newlib -+ * Have the 32 bit jiffies value wrap 5 minutes after boot -+ * so jiffies wrap bugs show up earlier. -+ */ -+//#define INITIAL_JIFFIES ((unsigned long)(unsigned int) (-300*HZ)) -+ -+struct sys_timer { -+// struct sys_device dev; -+ void (*init)(void); -+ void (*suspend)(void); -+ void (*resume)(void); -+ unsigned long (*offset)(void); -+}; -+ -+extern struct sys_timer *system_timer; -+extern void timer_tick( void); -+ -+/* -+ * Kernel time keeping support. -+ */ -+extern int (*set_rtc)(void); -+extern void save_time_delta(struct timespec *delta, struct timespec *rtc); -+extern void restore_time_delta(struct timespec *delta, struct timespec *rtc); -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mach-types.h linux-3.4.113/arch/nds32/include/asm/mach-types.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mach-types.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mach-types.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,14 @@ -+#ifndef __ASSEMBLY__ -+/* The type of machine we're running on */ -+extern unsigned int __machine_arch_type; -+#endif -+ -+#define MACH_TYPE_FARADAY 758 -+ -+# ifdef machine_arch_type -+# undef machine_arch_type -+# define machine_arch_type __machine_arch_type -+# else -+# define machine_arch_type MACH_TYPE_FARADAY -+# endif -+# define machine_is_faraday() (machine_arch_type == MACH_TYPE_FARADAY) -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/memory.h linux-3.4.113/arch/nds32/include/asm/memory.h ---- linux-3.4.113.orig/arch/nds32/include/asm/memory.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/memory.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,218 @@ -+/* -+ * linux/arch/nds32/include/asm/memory.h -+ * -+ * Copyright (C) 2000-2002 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Note: this file should not be included by non-asm/.h files -+ */ -+#ifndef __ASM_NDS32_MEMORY_H -+#define __ASM_NDS32_MEMORY_H -+ -+#include -+#ifndef __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ -+#define __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ -+ -+#include -+ -+#ifndef __ASSEMBLY__ -+#include -+#endif -+ -+#ifndef PHYS_OFFSET -+#define PHYS_OFFSET CPU_MEM_PA_BASE -+#endif -+ -+#ifndef PAGE_OFFSET -+#define PAGE_OFFSET (0xC0000000) -+#endif -+ -+#ifndef END_MEM -+#define END_MEM (CPU_MEM_PA_LIMIT) -+#endif -+ -+#ifndef __virt_to_bus -+#define __virt_to_bus __virt_to_phys -+#endif -+ -+#ifndef __bus_to_virt -+#define __bus_to_virt __phys_to_virt -+#endif -+ -+#endif /* __FARADAY_PLATFORM_INDEPENDENT_MEMORY_HEADER__ */ -+ -+#ifndef TASK_SIZE -+/* -+ * TASK_SIZE - the maximum size of a user space task. -+ * TASK_UNMAPPED_BASE - the lower boundary of the mmap VM area -+ */ -+#define TASK_SIZE (0xbf000000UL) -+#define TASK_UNMAPPED_BASE (0x40000000UL) -+#endif -+ -+/* -+ * Page offset: 3GB -+ */ -+#ifndef PAGE_OFFSET -+#define PAGE_OFFSET (0xc0000000) -+#endif -+ -+/* -+ * Physical vs virtual RAM address space conversion. These are -+ * private definitions which should NOT be used outside memory.h -+ * files. Use virt_to_phys/phys_to_virt/__pa/__va instead. -+ */ -+#ifndef __virt_to_phys -+#define __virt_to_phys(x) ((x) - PAGE_OFFSET + PHYS_OFFSET) -+#define __phys_to_virt(x) ((x) - PHYS_OFFSET + PAGE_OFFSET) -+#endif -+ -+/* -+ * The module space lives between the addresses given by TASK_SIZE -+ * and PAGE_OFFSET - it must be within 32MB of the kernel text. -+ */ -+#define MODULES_END (PAGE_OFFSET) -+#define MODULES_VADDR (MODULES_END - 16*1048576) -+ -+#if TASK_SIZE > MODULES_VADDR -+#error Top of user space clashes with start of module space -+#endif -+ -+#ifndef __ASSEMBLY__ -+ -+/* -+ * The DMA mask corresponding to the maximum bus address allocatable -+ * using GFP_DMA. The default here places no restriction on DMA -+ * allocations. This must be the smallest DMA mask in the system, -+ * so a successful GFP_DMA allocation will always satisfy this. -+ */ -+#ifndef ISA_DMA_THRESHOLD -+#define ISA_DMA_THRESHOLD (0xffffffffULL) -+#endif -+ -+#ifndef arch_adjust_zones -+#define arch_adjust_zones(node,size,holes) do { } while (0) -+#endif -+ -+/* -+ * PFNs are used to describe any physical page; this means -+ * PFN 0 == physical address 0. -+ * -+ * This is the PFN of the first RAM page in the kernel -+ * direct-mapped view. We assume this is the first page -+ * of RAM in the mem_map as well. -+ */ -+#define PHYS_PFN_OFFSET (PHYS_OFFSET >> PAGE_SHIFT) -+ -+/* -+ * These are *only* valid on the kernel direct mapped RAM memory. -+ * Note: Drivers should NOT use these. They are the wrong -+ * translation for translating DMA addresses. Use the driver -+ * DMA support - see dma-mapping.h. -+ */ -+static inline unsigned long virt_to_phys(void *x) -+{ -+ return __virt_to_phys((unsigned long)(x)); -+} -+ -+static inline void *phys_to_virt(unsigned long x) -+{ -+ return (void *)(__phys_to_virt((unsigned long)(x))); -+} -+ -+/* -+ * Drivers should NOT use these either. -+ */ -+#define __pa(x) __virt_to_phys((unsigned long)(x)) -+#define __va(x) ((void *)__phys_to_virt((unsigned long)(x))) -+ -+/* -+ * Virtual <-> DMA view memory address translations -+ * Again, these are *only* valid on the kernel direct mapped RAM -+ * memory. Use of these is *deprecated* (and that doesn't mean -+ * use the __ prefixed forms instead.) See dma-mapping.h. -+ */ -+static inline __deprecated unsigned long virt_to_bus(void *x) -+{ -+ return __virt_to_bus((unsigned long)x); -+} -+ -+static inline __deprecated void *bus_to_virt(unsigned long x) -+{ -+ return (void *)__bus_to_virt(x); -+} -+ -+/* -+ * Conversion between a struct page and a physical address. -+ * -+ * Note: when converting an unknown physical address to a -+ * struct page, the resulting pointer must be validated -+ * using VALID_PAGE(). It must return an invalid struct page -+ * for any physical address not corresponding to a system -+ * RAM address. -+ * -+ * pfn_valid(pfn) indicates whether a PFN number is valid -+ * -+ * virt_to_page(k) convert a _valid_ virtual address to struct page * -+ * virt_addr_valid(k) indicates whether a virtual address is valid -+ */ -+#ifndef CONFIG_DISCONTIGMEM -+ -+#define ARCH_PFN_OFFSET PHYS_PFN_OFFSET -+#define pfn_valid(pfn) ((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr)) -+ -+#define virt_to_page(kaddr) (pfn_to_page(__pa(kaddr) >> PAGE_SHIFT)) -+#define virt_addr_valid(kaddr) ((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory) -+ -+#define PHYS_TO_NID(addr) (0) -+ -+#else /* CONFIG_DISCONTIGMEM */ -+ -+/* -+ * This is more complex. We have a set of mem_map arrays spread -+ * around in memory. -+ */ -+#include -+ -+#define pfn_valid(pfn) (PFN_TO_NID(pfn) < MAX_NUMNODES) -+ -+#define virt_to_page(kaddr) \ -+ (ADDR_TO_MAPBASE(kaddr) + LOCAL_MAP_NR(kaddr)) -+#define virt_addr_valid(kaddr) (KVADDR_TO_NID(kaddr) < MAX_NUMNODES) -+ -+/* -+ * Common discontigmem stuff. -+ * PHYS_TO_NID is used by the NDS32 kernel/setup.c -+ */ -+#define PHYS_TO_NID(addr) PFN_TO_NID((addr) >> PAGE_SHIFT) -+ -+#endif /* !CONFIG_DISCONTIGMEM */ -+ -+/* -+ * For BIO. "will die". Kill me when bio_to_phys() and bvec_to_phys() die. -+ */ -+#define page_to_phys(page) (page_to_pfn(page) << PAGE_SHIFT) -+ -+/* -+ * Optional device DMA address remapping. Do _not_ use directly! -+ * We should really eliminate virt_to_bus() here - it's deprecated. -+ */ -+#ifndef __arch_page_to_dma -+#define page_to_dma(dev, page) ((dma_addr_t)__virt_to_bus((unsigned long)page_address(page))) -+#define dma_to_virt(dev, addr) ((void *)__bus_to_virt(addr)) -+#define virt_to_dma(dev, addr) ((dma_addr_t)__virt_to_bus((unsigned long)(addr))) -+#else -+#define page_to_dma(dev, page) (__arch_page_to_dma(dev, page)) -+#define dma_to_virt(dev, addr) (__arch_dma_to_virt(dev, addr)) -+#define virt_to_dma(dev, addr) (__arch_virt_to_dma(dev, addr)) -+#endif -+ -+#endif -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/misc_spec.h linux-3.4.113/arch/nds32/include/asm/misc_spec.h ---- linux-3.4.113.orig/arch/nds32/include/asm/misc_spec.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/misc_spec.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,75 @@ -+/* -+ * linux/arch/nds32/include/asm/misc_spec.h -+ * -+ * Faraday A320D platform dependent definitions -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/14/2005 Created -+ * Luke Lee 10/06/2005 Modified for automatic system clock rate -+ */ -+ -+#ifndef __A320_PLATFORM_MANUAL_DEFINITION__ -+#define __A320_PLATFORM_MANUAL_DEFINITION__ -+ -+#define BOOT_PARAMETER_PA_BASE (PHYS_OFFSET + 0x400) -+ -+#ifdef CONFIG_AUTO_SYS_CLK -+ -+#ifndef __ASSEMBLY__ -+extern int ag101_get_ahb_clk(void); -+extern int ag102_get_ahb_clk(void); -+ -+#if defined(CONFIG_PLAT_AG101) -+#define AHB_CLK_IN ag101_get_ahb_clk() -+#elif defined(CONFIG_PLAT_AG102) -+#define AHB_CLK_IN ag102_get_ahb_clk() -+ -+#endif -+ -+#endif -+#define TIMER_CLK_IN (CONFIG_SYS_CLK/2) -+ -+#else -+ -+/* Timer clock input is APB CLOCK */ -+#define TIMER_CLK_IN (CONFIG_SYS_CLK/2) -+#define AHB_CLK_IN (CONFIG_SYS_CLK) -+ -+#endif -+ -+#ifndef __ASSEMBLY__ -+#include -+ -+#ifdef CONFIG_PLATFORM_INTC -+extern void __init intc_ftintc010_init_irq(void); -+#define platform_init_irq intc_ftintc010_init_irq -+#endif -+ -+#ifdef CONFIG_PLATFORM_NOINTC -+extern void __init nointc_init_irq(void); -+#define platform_init_irq nointc_init_irq -+#endif -+ -+#endif -+ -+#define daughter_platform_init_irq(x) /* NOP */ -+ -+#endif /*__A320_PLATFORM_MANUAL_DEFINITION__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mman.h linux-3.4.113/arch/nds32/include/asm/mman.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mman.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mman.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,22 @@ -+/* -+ * linux/arch/nds32/include/asm/mman.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_MMAN_H__ -+#define __NDS32_MMAN_H__ -+ -+#include -+ -+#define MAP_GROWSDOWN 0x0100 /* stack-like segment */ -+#define MAP_DENYWRITE 0x0800 /* ETXTBSY */ -+#define MAP_EXECUTABLE 0x1000 /* mark it as an executable */ -+#define MAP_LOCKED 0x2000 /* pages are locked */ -+#define MAP_NORESERVE 0x4000 /* don't check for reservations */ -+#define MAP_POPULATE 0x8000 /* populate (prefault) page tables */ -+#define MAP_NONBLOCK 0x10000 /* do not block on IO */ -+ -+#define MCL_CURRENT 1 /* lock all current mappings */ -+#define MCL_FUTURE 2 /* lock all future mappings */ -+ -+#endif /* __NDS32_MMAN_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mmu_context.h linux-3.4.113/arch/nds32/include/asm/mmu_context.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mmu_context.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mmu_context.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,84 @@ -+/* -+ * linux/arch/nds32/include/asm/mmu_context.h -+ * -+ * Copyright (C) 1996 Russell King. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Changelog: -+ * 27-06-1996 RMK Created -+ */ -+#ifndef __ASM_NDS32_MMU_CONTEXT_H -+#define __ASM_NDS32_MMU_CONTEXT_H -+ -+#include -+#include -+#include -+ -+static inline int -+init_new_context(struct task_struct *tsk, struct mm_struct *mm) -+{ -+ mm->context.id = 0; -+ return 0; -+} -+ -+#define destroy_context(mm) do { } while(0) -+ -+#ifndef CONFIG_CPU_NO_CONTEXT_ID -+#define CID_BITS 9 -+extern spinlock_t cid_lock; -+extern unsigned int cpu_last_cid; -+ -+static inline void -+__new_context(struct mm_struct *mm) -+{ -+ unsigned int cid; -+ unsigned long flags; -+ -+ spin_lock_irqsave(&cid_lock, flags); -+ cid = cpu_last_cid; -+ cpu_last_cid += 1 << TLB_MISC_offCID; -+ if (cpu_last_cid == 0) -+ cpu_last_cid = 1 << TLB_MISC_offCID << CID_BITS; -+ spin_unlock_irqrestore(&cid_lock, flags); -+ -+ if ((cid & TLB_MISC_mskCID ) == 0) -+ flush_tlb_all(); -+ -+ mm->context.id = cid; -+} -+ -+static inline void -+check_context(struct mm_struct *mm) -+{ -+ if (unlikely((mm->context.id ^ cpu_last_cid) >> TLB_MISC_offCID >> CID_BITS)) -+ __new_context(mm); -+} -+#else -+#define check_context(m) -+#endif -+ -+static inline void -+enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) -+{ -+} -+ -+static inline void -+switch_mm(struct mm_struct *prev, struct mm_struct *next, -+ struct task_struct *tsk) -+{ -+ unsigned int cpu = smp_processor_id(); -+ -+ if (!cpumask_test_and_set_cpu(cpu, mm_cpumask(next)) || prev != next) { -+ check_context(next); -+ cpu_switch_mm(next); -+ } -+} -+ -+#define deactivate_mm(tsk,mm) do { } while (0) -+#define activate_mm(prev,next) switch_mm(prev, next, NULL) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mmu.h linux-3.4.113/arch/nds32/include/asm/mmu.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mmu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mmu.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,42 @@ -+/* -+ * linux/arch/nds32/include/asm/mmu.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_MMU_H -+#define __NDS32_MMU_H -+ -+typedef struct { -+ unsigned int id; -+} mm_context_t; -+ -+#define ASID(mm) ((mm)->context.id & (TLB_MISC_mskCID >> TLB_MISC_offCID)) -+inline static unsigned long ACC_PSZ(unsigned long page_size) -+{ -+ switch(page_size) { -+ case(1<<12): -+ return 0; -+ case(1<<13): -+ return 1; -+ case(1<<14): -+ return 2; -+ case(1<<16): -+ return 3; -+ case(1<<18): -+ return 4; -+ case(1<<20): -+ return 5; -+ case(1<<22): -+ return 6; -+ case(1<<24): -+ return 7; -+ case(1<<26): -+ return 8; -+ case(1<<28): -+ return 9; -+ default: -+ printk("Huge Page Size is not supported \n"); -+ return 0xffffffff; -+ } -+} -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/module.h linux-3.4.113/arch/nds32/include/asm/module.h ---- linux-3.4.113.orig/arch/nds32/include/asm/module.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/module.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,23 @@ -+/* -+ * linux/arch/nds32/include/asm/module.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASM_NDS32_MODULE_H -+#define _ASM_NDS32_MODULE_H -+ -+struct mod_arch_specific -+{ -+ int foo; -+}; -+ -+#define Elf_Shdr Elf32_Shdr -+#define Elf_Sym Elf32_Sym -+#define Elf_Ehdr Elf32_Ehdr -+ -+/* -+ * Include the ARM architecture version. -+ */ -+#define MODULE_ARCH_VERMAGIC "NDS32vN10" __stringify(__LINUX_NDS32_ARCH__) " " -+ -+#endif /* _ASM_NDS32_MODULE_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/msgbuf.h linux-3.4.113/arch/nds32/include/asm/msgbuf.h ---- linux-3.4.113.orig/arch/nds32/include/asm/msgbuf.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/msgbuf.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * linux/arch/nds32/include/asm/msgbuf.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_MSGBUF_H -+#define _ASMNDS32_MSGBUF_H -+ -+/* -+ * The msqid64_ds structure for arm architecture. -+ * Note extra padding because this structure is passed back and forth -+ * between kernel and user space. -+ * -+ * Pad space is left for: -+ * - 64-bit time_t to solve y2038 problem -+ * - 2 miscellaneous 32-bit values -+ */ -+ -+struct msqid64_ds { -+ struct ipc64_perm msg_perm; -+ __kernel_time_t msg_stime; /* last msgsnd time */ -+ unsigned long __unused1; -+ __kernel_time_t msg_rtime; /* last msgrcv time */ -+ unsigned long __unused2; -+ __kernel_time_t msg_ctime; /* last change time */ -+ unsigned long __unused3; -+ unsigned long msg_cbytes; /* current number of bytes on queue */ -+ unsigned long msg_qnum; /* number of messages in queue */ -+ unsigned long msg_qbytes; /* max number of bytes on queue */ -+ __kernel_pid_t msg_lspid; /* pid of last msgsnd */ -+ __kernel_pid_t msg_lrpid; /* last receive pid */ -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+ -+#endif /* _ASMNDS32_MSGBUF_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/mutex.h linux-3.4.113/arch/nds32/include/asm/mutex.h ---- linux-3.4.113.orig/arch/nds32/include/asm/mutex.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/mutex.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/mutex.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_MUTEX_H__ -+#define __NDS32_MUTEX_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/namei.h linux-3.4.113/arch/nds32/include/asm/namei.h ---- linux-3.4.113.orig/arch/nds32/include/asm/namei.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/namei.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/namei.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_NAMEI_H__ -+#define __NDS32_NAMEI_H__ -+ -+#define __emul_prefix() NULL -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/nds32.h linux-3.4.113/arch/nds32/include/asm/nds32.h ---- linux-3.4.113.orig/arch/nds32/include/asm/nds32.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/nds32.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,90 @@ -+/* -+ * linux/arch/nds32/include/asm/nds32.h -- Andes NDS32 processor register interface -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2006 Andes Technology Corporation -+ * -+ */ -+#ifndef _ASM_NDS32_NDS32_H_ -+#define _ASM_NDS32_NDS32_H_ -+ -+#include -+#include -+ -+#define MSYNC( subtype) __asm__ ("\n\tmsync "#subtype); -+#define STANDBY( cond) __asm__ ("\n\tstandby "#cond); -+ -+#ifndef __ASSEMBLY__ -+ -+static inline void ISB( void) { __asm__ ("\n\tisb"); } -+static inline void DSB( void) { __asm__ ("\n\tdsb"); } -+ -+static inline void GIE_ENABLE( void) -+{ -+ __asm__ ("gie_enable\n\t"); -+} -+ -+static inline void GIE_DISABLE( void) -+{ -+ __asm__ ("gie_disable\n\t"); -+} -+ -+enum cache_t{ ICACHE, DCACHE}; -+ -+static inline unsigned long CACHE_SET( enum cache_t cache){ -+ -+ if( cache == ICACHE) -+ return 64 << ( ( GET_ICM_CFG() & ICM_CFG_mskISET) >> ICM_CFG_offISET); -+ else -+ return 64 << ( ( GET_DCM_CFG() & DCM_CFG_mskDSET) >> DCM_CFG_offDSET); -+} -+ -+static inline unsigned long CACHE_WAY( enum cache_t cache){ -+ -+ if( cache == ICACHE) -+ return 1 + ( ( GET_ICM_CFG() & ICM_CFG_mskIWAY) >> ICM_CFG_offIWAY); -+ else -+ return 1 + ( ( GET_DCM_CFG() & DCM_CFG_mskDWAY) >> DCM_CFG_offDWAY); -+} -+ -+static inline unsigned long CACHE_LINE_SIZE( enum cache_t cache){ -+ -+ if( cache == ICACHE) -+ return 8 << ( ( ( GET_ICM_CFG() & ICM_CFG_mskISZ) >> ICM_CFG_offISZ) - 1); -+ else -+ return 8 << ( ( ( GET_DCM_CFG() & DCM_CFG_mskDSZ) >> DCM_CFG_offDSZ) - 1); -+} -+ -+static inline void GIE_SAVE( unsigned long *var){ -+ -+ *var = GET_PSW(); -+ GIE_DISABLE(); -+} -+ -+static inline void GIE_RESTORE( unsigned long var){ -+ -+ if( var & PSW_mskGIE){ -+ GIE_ENABLE(); -+ } -+} -+ -+#endif /* __ASSEMBLY__ */ -+ -+#define IVB_BASE PHYS_OFFSET /* in user space for intr/exc/trap/break table base, 64KB aligned -+ * We defined at the start of the physical memory */ -+ -+/* The following dispatching entry */ -+#define ENTRY_TLB_MISC (IVB_BASE + nrTLB_MISC*vENTRY_SZ) /* TLB misc eh# */ -+/* dispatched sub-entry exception handler numbering */ -+#define RD_PROT 0 /* read protrection */ -+#define WRT_PROT 1 /* write protection */ -+#define NOEXEC 2 /* non executable */ -+#define PAGE_MODIFY 3 /* page modified */ -+#define ACC_BIT 4 /* access bit */ -+#define RESVED_PTE 5 /* reserved PTE attribute */ -+/* reserved 6 ~ 16 */ -+ -+#endif /* _ASM_NDS32_NDS32_H_ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/numnodes.h linux-3.4.113/arch/nds32/include/asm/numnodes.h ---- linux-3.4.113.orig/arch/nds32/include/asm/numnodes.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/numnodes.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * linux/arch/nds32/include/asm/numnodes.h -+ * -+ * Copyright (C) 2002 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ */ -+ -+/* This declaration for the size of the NUMA (CONFIG_DISCONTIGMEM) -+ * memory node table is the default. -+ * -+ * A good place to override this value is include/asm/arch/memory.h. -+ */ -+ -+#ifndef __ASM_NDS32_NUMNODES_H -+#define __ASM_NDS32_NUMNODES_H -+ -+#ifndef NODES_SHIFT -+# define NODES_SHIFT 2 /* Normally, Max 4 Nodes */ -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/page.h linux-3.4.113/arch/nds32/include/asm/page.h ---- linux-3.4.113.orig/arch/nds32/include/asm/page.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/page.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,153 @@ -+/* -+ * linux/arch/nds32/include/asm/page.h -+ * -+ * Copyright (C) 1995-2003 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef _ASMNDS32_PAGE_H -+#define _ASMNDS32_PAGE_H -+ -+ -+#ifdef CONFIG_ANDES_PAGE_SIZE_4KB -+#define PAGE_SHIFT 12 -+#endif -+#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -+#define PAGE_SHIFT 13 -+#endif -+#include -+#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT) -+#define PAGE_MASK (~(PAGE_SIZE-1)) -+#define PTE_MASK PAGE_MASK -+ -+/* PAGE_SHIFT determines the page size */ -+#define EXEC_PAGESIZE PAGE_SIZE -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_16KB -+#define LARGE_PAGE_SHIFT 14 -+#define HPAGE_SHIFT 14 -+#endif -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_64KB -+#define LARGE_PAGE_SHIFT 16 -+#define HPAGE_SHIFT 16 -+#endif -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_256KB -+#define LARGE_PAGE_SHIFT 18 -+#define HPAGE_SHIFT 18 -+#endif -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_1MB -+#define LARGE_PAGE_SHIFT 20 -+#define HPAGE_SHIFT 20 -+#endif -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_4MB -+#define LARGE_PAGE_SHIFT 22 -+#define HPAGE_SHIFT 22 -+#endif -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_16MB -+#define LARGE_PAGE_SHIFT 24 -+#define HPAGE_SHIFT 24 -+#endif -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_64MB -+#define LARGE_PAGE_SHIFT 26 -+#define HPAGE_SHIFT 26 -+#endif -+ -+#ifdef CONFIG_ANDES_HUGETLB_PAGE_SIZE_256MB -+#define LARGE_PAGE_SHIFT 28 -+#define HPAGE_SHIFT 28 -+#endif -+ -+#ifdef CONFIG_HUGETLB_PAGE -+// taken for i386 style -+#define LARGE_PAGE_SIZE (1UL << LARGE_PAGE_SHIFT) -+#define LARGE_PAGE_MASK (~(LARGE_PAGE_SIZE-1)) -+// taken for SH style -+#define HPAGE_SIZE (1UL << HPAGE_SHIFT) -+#define HPAGE_MASK (~(HPAGE_SIZE-1)) -+#define HUGETLB_PAGE_ORDER (HPAGE_SHIFT-PAGE_SHIFT) -+#endif -+ -+ -+#ifdef __KERNEL__ -+ -+#ifndef __ASSEMBLY__ -+ -+struct page; -+struct vm_area_struct; -+#ifndef CONFIG_CPU_CACHE_NONALIASING -+extern void copy_user_highpage(struct page *to, struct page *from, -+ unsigned long vaddr, struct vm_area_struct *vma); -+extern void clear_user_highpage(struct page *page, unsigned long vaddr); -+ -+#define __HAVE_ARCH_COPY_USER_HIGHPAGE -+#define clear_user_highpage clear_user_highpage -+#else -+#define clear_user_page(page, vaddr, pg) clear_page(page) -+#define copy_user_page(to, from, vaddr, pg) copy_page(to, from) -+#endif -+ -+void clear_page(void *page); -+void copy_page(void *to, void *from); -+ -+#undef STRICT_MM_TYPECHECKS -+ -+#ifdef STRICT_MM_TYPECHECKS -+/* -+ * These are used to make use of C type-checking.. -+ */ -+typedef struct { unsigned long pte; } pte_t; -+typedef struct { unsigned long pmd; } pmd_t; -+typedef struct { unsigned long pgd; } pgd_t; -+typedef struct { unsigned long pgprot; } pgprot_t; -+ -+#define pte_val(x) ((x).pte) -+#define pmd_val(x) ((x).pmd) -+#define pgd_val(x) ((x).pgd) -+#define pgprot_val(x) ((x).pgprot) -+ -+#define __pte(x) ((pte_t) { (x) } ) -+#define __pmd(x) ((pmd_t) { (x) } ) -+#define __pgd(x) ((pgd_t) { (x) } ) -+#define __pgprot(x) ((pgprot_t) { (x) } ) -+ -+#else -+/* -+ * .. while these make it easier on the compiler -+ */ -+typedef unsigned long pte_t; -+typedef unsigned long pmd_t; -+typedef unsigned long pgd_t; -+typedef unsigned long pgprot_t; -+ -+#define pte_val(x) (x) -+#define pmd_val(x) (x) -+#define pgd_val(x) (x) -+#define pgprot_val(x) (x) -+ -+#define __pte(x) (x) -+#define __pmd(x) (x) -+#define __pgd(x) (x) -+#define __pgprot(x) (x) -+ -+#endif /* STRICT_MM_TYPECHECKS */ -+typedef struct page *pgtable_t; -+ -+#include -+#include -+ -+#endif /* !__ASSEMBLY__ */ -+ -+#define VM_DATA_DEFAULT_FLAGS (VM_READ | VM_WRITE | VM_EXEC | \ -+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) -+ -+#endif /* __KERNEL__ */ -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/param.h linux-3.4.113/arch/nds32/include/asm/param.h ---- linux-3.4.113.orig/arch/nds32/include/asm/param.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/param.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * linux/arch/nds32/include/asm/param.h -+ * -+ * Copyright (C) 1995-1999 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_PARAM_H -+#define __ASM_PARAM_H -+ -+#ifdef __KERNEL__ -+ -+# ifndef HZ -+# define HZ CONFIG_HZ /* Internal kernel timer frequency */ -+# endif -+ -+# define USER_HZ HZ /* User interfaces are in "ticks" */ -+# define CLOCKS_PER_SEC (USER_HZ) /* like times() */ -+#else -+# define HZ 100 -+#endif -+ -+//#define EXEC_PAGESIZE 4096 -+ -+#ifndef NOGROUP -+#define NOGROUP (-1) -+#endif -+ -+/* max length of hostname */ -+#define MAXHOSTNAMELEN 64 -+ -+#endif -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/parport.h linux-3.4.113/arch/nds32/include/asm/parport.h ---- linux-3.4.113.orig/arch/nds32/include/asm/parport.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/parport.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,19 @@ -+/* -+ * linux/arch/nds32/include/asm/parport.h: NDS32-specific parport initialisation -+ * -+ * Copyright (C) 1999, 2000 Tim Waugh -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This file should only be included by drivers/parport/parport_pc.c. -+ */ -+ -+#ifndef __ASMNDS32_PARPORT_H -+#define __ASMNDS32_PARPORT_H -+ -+static int __devinit parport_pc_find_isa_ports (int autoirq, int autodma); -+static int __devinit parport_pc_find_nonpci_ports (int autoirq, int autodma) -+{ -+ return parport_pc_find_isa_ports (autoirq, autodma); -+} -+ -+#endif /* !(_ASMNDS32_PARPORT_H) */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/pci.h linux-3.4.113/arch/nds32/include/asm/pci.h ---- linux-3.4.113.orig/arch/nds32/include/asm/pci.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/pci.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,77 @@ -+/* -+ * linux/arch/nds32/include/asm/pci.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef ASMNDS32_PCI_H -+#define ASMNDS32_PCI_H -+ -+#ifdef __KERNEL__ -+#include -+ -+#include /* for PCIBIOS_MIN_* */ -+ -+#define pcibios_scan_all_fns(a, b) 0 -+ -+static inline void pcibios_set_master(struct pci_dev *dev) -+{ -+ /* No special bus mastering setup handling */ -+} -+ -+static inline void pcibios_penalize_isa_irq(int irq) -+{ -+ /* We don't do dynamic PCI IRQ allocation */ -+} -+ -+/* -+ * The PCI address space does equal the physical memory address space. -+ * The networking and block device layers use this boolean for bounce -+ * buffer decisions. -+ */ -+#define PCI_DMA_BUS_IS_PHYS (0) -+ -+/* -+ * Whether pci_unmap_{single,page} is a nop depends upon the -+ * configuration. -+ */ -+#define DECLARE_PCI_UNMAP_ADDR(ADDR_NAME) dma_addr_t ADDR_NAME; -+#define DECLARE_PCI_UNMAP_LEN(LEN_NAME) __u32 LEN_NAME; -+#define pci_unmap_addr(PTR, ADDR_NAME) ((PTR)->ADDR_NAME) -+#define pci_unmap_addr_set(PTR, ADDR_NAME, VAL) (((PTR)->ADDR_NAME) = (VAL)) -+#define pci_unmap_len(PTR, LEN_NAME) ((PTR)->LEN_NAME) -+#define pci_unmap_len_set(PTR, LEN_NAME, VAL) (((PTR)->LEN_NAME) = (VAL)) -+ -+#define HAVE_PCI_MMAP -+extern int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, -+ enum pci_mmap_state mmap_state, int write_combine); -+ -+extern void -+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -+ struct resource *res); -+ -+extern void -+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -+ struct pci_bus_region *region); -+ -+static inline struct resource * -+pcibios_select_root(struct pci_dev *pdev, struct resource *res) -+{ -+ struct resource *root = NULL; -+ -+ if (res->flags & IORESOURCE_IO) -+ root = &ioport_resource; -+ if (res->flags & IORESOURCE_MEM) -+ root = &iomem_resource; -+ -+ return root; -+} -+ -+#endif /* __KERNEL__ */ -+ -+/* Chances are this interrupt is wired PC-style ... */ -+static inline int pci_get_legacy_ide_irq(struct pci_dev *dev, int channel) -+{ -+ return channel ? 15 : 14; -+} -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/percpu.h linux-3.4.113/arch/nds32/include/asm/percpu.h ---- linux-3.4.113.orig/arch/nds32/include/asm/percpu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/percpu.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/percpu.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_PERCPU -+#define __NDS32_PERCPU -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/pfm.h linux-3.4.113/arch/nds32/include/asm/pfm.h ---- linux-3.4.113.orig/arch/nds32/include/asm/pfm.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/pfm.h 2016-12-01 20:59:24.340612287 +0100 -@@ -0,0 +1,16 @@ -+#ifndef __PFM_H_ -+#define __PFM_H_ -+ -+struct pcounter { -+ unsigned long long pfm0; /* value of $PFMC0 */ -+ unsigned long long pfm1; /* value of $PFMC1 */ -+ unsigned long long pfm2; /* value of $PFMC2 */ -+}; -+ -+#ifdef __KERNEL__ -+void sys_pfmctl(int event0, int event1, int event2, int start); -+int sys_getpfm(struct pcounter __user *p); -+int sys_setpfm(int pfm0, int pfm1, int pfm2, struct pcounter __user *p); -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/pgalloc.h linux-3.4.113/arch/nds32/include/asm/pgalloc.h ---- linux-3.4.113.orig/arch/nds32/include/asm/pgalloc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/pgalloc.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,104 @@ -+/* -+ * linux/arch/nds32/include/asm/pgalloc.h -+ * -+ * Copyright (C) 2000-2001 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef _ASMNDS32_PGALLOC_H -+#define _ASMNDS32_PGALLOC_H -+ -+#include -+#include -+#include -+ -+/* -+ * Since we have only two-level page tables, these are trivial -+ */ -+#define pmd_alloc_one(mm, addr) ({ BUG(); ((pmd_t *)2); }) -+#define pmd_free(mm, pmd) do { } while (0) -+#define pgd_populate(mm, pmd, pte) BUG() -+#define pmd_pgtable(pmd) pmd_page(pmd) -+ -+extern pgd_t *get_pgd_slow(struct mm_struct *mm); -+extern void free_pgd_slow(struct mm_struct *mm, pgd_t *pgd); -+ -+#define pgd_alloc(mm) get_pgd_slow(mm) -+#define pgd_free(mm, pgd) free_pgd_slow(mm, pgd) -+ -+#define check_pgt_cache() do { } while (0) -+ -+static inline pte_t * -+pte_alloc_one_kernel(struct mm_struct *mm, unsigned long addr) -+{ -+ pte_t *pte; -+ -+ pte = (pte_t *)__get_free_page(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO); -+ -+ return pte; -+} -+ -+static inline pgtable_t -+pte_alloc_one(struct mm_struct *mm, unsigned long addr) -+{ -+ pgtable_t pte; -+ -+ pte = alloc_pages(GFP_KERNEL|__GFP_REPEAT|__GFP_ZERO, 0); -+ if (pte) -+ cpu_dcache_wb_page((unsigned long)page_address(pte)); -+ -+ return pte; -+} -+ -+/* -+ * Free one PTE table. -+ */ -+static inline void pte_free_kernel(struct mm_struct *mm, pte_t *pte) -+{ -+ if (pte) { -+ free_page((unsigned long)pte); -+ } -+} -+ -+static inline void pte_free(struct mm_struct *mm, pgtable_t pte) -+{ -+ __free_page(pte); -+} -+ -+/* -+ * Populate the pmdp entry with a pointer to the pte. This pmd is part -+ * of the mm address space. -+ * -+ * Ensure that we always set both PMD entries. -+ */ -+static inline void -+pmd_populate_kernel(struct mm_struct *mm, pmd_t *pmdp, pte_t *ptep) -+{ -+ unsigned long pte_ptr = (unsigned long)ptep; -+ unsigned long pmdval; -+ -+ BUG_ON(mm != &init_mm); -+ -+ /* -+ * The pmd must be loaded with the physical -+ * address of the PTE table -+ */ -+ pmdval = __pa(pte_ptr) | _PAGE_KERNEL_TABLE; -+ set_pmd(pmdp, __pmd(pmdval)); -+} -+ -+static inline void -+pmd_populate(struct mm_struct *mm, pmd_t *pmdp, pgtable_t ptep) -+{ -+ unsigned long pmdval; -+ -+ BUG_ON(mm == &init_mm); -+ -+ pmdval = page_to_pfn(ptep) << PAGE_SHIFT | _PAGE_USER_TABLE; -+ set_pmd(pmdp, __pmd(pmdval)); -+} -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/pgtable.h linux-3.4.113/arch/nds32/include/asm/pgtable.h ---- linux-3.4.113.orig/arch/nds32/include/asm/pgtable.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/pgtable.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,429 @@ -+/* -+ * linux/arch/nds32/include/asm/pgtable.h -+ * -+ * Copyright (C) 1995-2002 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef _ASMNDS32_PGTABLE_H -+#define _ASMNDS32_PGTABLE_H -+ -+#include -+#include -+ -+#include -+#include -+#include -+#ifndef __ASSEMBLY__ -+#include -+#endif -+ -+#ifdef CONFIG_CACHE_L2 -+#include -+#endif -+ -+#ifdef CONFIG_ANDES_PAGE_SIZE_4KB -+#define PGDIR_SHIFT 22 -+#define PTRS_PER_PGD 1024 -+#define PMD_SHIFT 22 -+#define PTRS_PER_PMD 1 -+#define PTRS_PER_PTE 1024 -+#endif -+ -+#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -+#define PGDIR_SHIFT 24 -+#define PTRS_PER_PGD 256 -+#define PMD_SHIFT 24 -+#define PTRS_PER_PMD 1 -+#define PTRS_PER_PTE 2048 -+#endif -+ -+#ifndef __ASSEMBLY__ -+extern void __pte_error(const char *file, int line, unsigned long val); -+extern void __pmd_error(const char *file, int line, unsigned long val); -+extern void __pgd_error(const char *file, int line, unsigned long val); -+ -+#define pte_ERROR(pte) __pte_error(__FILE__, __LINE__, pte_val(pte)) -+#define pmd_ERROR(pmd) __pmd_error(__FILE__, __LINE__, pmd_val(pmd)) -+#define pgd_ERROR(pgd) __pgd_error(__FILE__, __LINE__, pgd_val(pgd)) -+#endif /* !__ASSEMBLY__ */ -+ -+#define PMD_SIZE (1UL << PMD_SHIFT) -+#define PMD_MASK (~(PMD_SIZE-1)) -+#define PGDIR_SIZE (1UL << PGDIR_SHIFT) -+#define PGDIR_MASK (~(PGDIR_SIZE-1)) -+ -+/* -+ * This is the lowest virtual address we can permit any user space -+ * mapping to be mapped at. This is particularly important for -+ * non-high vector CPUs. -+ */ -+#define FIRST_USER_ADDRESS 0x8000 -+ -+#define VMALLOC_OFFSET (8 * 1024 * 1024) -+#define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) -+#define VMALLOC_VMADDR(x) ((unsigned long)(x)) -+ -+ -+#ifdef CONFIG_HIGHMEM -+#define CONSISTENT_BASE ((PKMAP_BASE) - (SZ_2M)) -+#define CONSISTENT_END (PKMAP_BASE) -+#else -+#define CONSISTENT_BASE (FIXADDR_START - SZ_2M) -+#define CONSISTENT_END (FIXADDR_START) -+#endif -+#define CONSISTENT_OFFSET(x) (((unsigned long)(x) - CONSISTENT_BASE) >> PAGE_SHIFT) -+ -+#ifdef CONFIG_HIGHMEM -+#ifndef __ASSEMBLY__ -+#include -+#endif -+#endif -+ -+//# define VMALLOC_END (CONSISTENT_START - PAGE_SIZE) -+# define VMALLOC_END (0xf9000000) -+ -+#define VMALLOC_RESERVE (128 << 20) -+#define MAXMEM (VMALLOC_END - PAGE_OFFSET - VMALLOC_RESERVE) -+#define MAXMEM_PFN PFN_DOWN(MAXMEM) -+ -+#define FIRST_USER_PGD_NR 0 -+#define USER_PTRS_PER_PGD ((TASK_SIZE/PGDIR_SIZE) + FIRST_USER_PGD_NR) -+ -+/* L2 PTE */ -+#define _PAGE_V (1UL << 0) -+ -+#define _PAGE_M_XKRW (0UL << 1) -+#define _PAGE_M_UR_KR (1UL << 1) -+#define _PAGE_M_UR_KRW (2UL << 1) -+#define _PAGE_M_URW_KRW (3UL << 1) -+#define _PAGE_M_KR (5UL << 1) -+#define _PAGE_M_KRW (7UL << 1) -+ -+#define _PAGE_D (1UL << 4) -+#define _PAGE_E (1UL << 5) -+#define _PAGE_A (1UL << 6) -+#define _PAGE_G (1UL << 7) -+ -+#define _PAGE_C_DEV (0UL << 8) -+#define _PAGE_C_DEV_WB (1UL << 8) -+#define _PAGE_C_MEM (2UL << 8) -+#define _PAGE_C_MEM_SHRD_WB (4UL << 8) -+#define _PAGE_C_MEM_SHRD_WT (5UL << 8) -+#define _PAGE_C_MEM_WB (6UL << 8) -+#define _PAGE_C_MEM_WT (7UL << 8) -+ -+#define _PAGE_L (1UL << 11) -+ -+#ifndef CONFIG_NO_KERNEL_LARGE_PAGE -+#define _HAVE_PAGE_L (_PAGE_L) -+#else -+#define _HAVE_PAGE_L 0 -+#endif -+#define _PAGE_FILE (1UL << 1) -+#define _PAGE_YOUNG 0 -+#define _PAGE_M_MASK _PAGE_M_KRW -+#define _PAGE_C_MASK _PAGE_C_MEM_WT -+ -+#ifdef CONFIG_SMP -+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -+#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WT -+#else -+#define _PAGE_CACHE_SHRD _PAGE_C_MEM_SHRD_WB -+#endif -+#else -+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -+#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WT -+#else -+#define _PAGE_CACHE_SHRD _PAGE_C_MEM_WB -+#endif -+#endif -+ -+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -+#define _PAGE_CACHE _PAGE_C_MEM_WT -+#else -+#define _PAGE_CACHE _PAGE_C_MEM_WB -+#endif -+ -+/* -+ * + Level 1 descriptor (PMD) -+ */ -+#define PMD_TYPE_TABLE 0 -+ -+#ifndef __ASSEMBLY__ -+ -+#define _PAGE_USER_TABLE PMD_TYPE_TABLE -+#define _PAGE_KERNEL_TABLE PMD_TYPE_TABLE -+ -+#define PAGE_EXEC __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_E) -+#define PAGE_NONE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_A) -+#define PAGE_READ __pgprot(_PAGE_V | _PAGE_M_UR_KR) -+#define PAGE_RDWR __pgprot(_PAGE_V | _PAGE_M_URW_KRW | _PAGE_D) -+#define PAGE_COPY __pgprot(_PAGE_V | _PAGE_M_UR_KR) -+ -+#define PAGE_UXKRWX_V1 __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -+#define PAGE_UXKRWX_V2 __pgprot(_PAGE_V | _PAGE_M_XKRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -+#define PAGE_CACHE_L1 __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE) -+#define PAGE_MEMORY __pgprot(_HAVE_PAGE_L | _PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -+#define PAGE_KERNEL __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_E | _PAGE_G | _PAGE_CACHE_SHRD) -+#define PAGE_DEVICE __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | _PAGE_G | _PAGE_C_DEV) -+#endif /* __ASSEMBLY__ */ -+ -+/* xwr */ -+#define __P000 (PAGE_NONE | _PAGE_CACHE_SHRD) -+#define __P001 (PAGE_READ | _PAGE_CACHE_SHRD) -+#define __P010 (PAGE_COPY | _PAGE_CACHE_SHRD) -+#define __P011 (PAGE_COPY | _PAGE_CACHE_SHRD) -+#define __P100 (PAGE_EXEC | _PAGE_CACHE_SHRD) -+#define __P101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) -+#define __P110 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) -+#define __P111 (PAGE_COPY | _PAGE_E | _PAGE_CACHE_SHRD) -+ -+#define __S000 (PAGE_NONE | _PAGE_CACHE_SHRD) -+#define __S001 (PAGE_READ | _PAGE_CACHE_SHRD) -+#define __S010 (PAGE_RDWR | _PAGE_CACHE_SHRD) -+#define __S011 (PAGE_RDWR | _PAGE_CACHE_SHRD) -+#define __S100 (PAGE_EXEC | _PAGE_CACHE_SHRD) -+#define __S101 (PAGE_READ | _PAGE_E | _PAGE_CACHE_SHRD) -+#define __S110 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) -+#define __S111 (PAGE_RDWR | _PAGE_E | _PAGE_CACHE_SHRD) -+ -+#ifndef __ASSEMBLY__ -+/* -+ * ZERO_PAGE is a global shared page that is always zero: used -+ * for zero-mapped memory areas etc.. -+ */ -+extern struct page *empty_zero_page; -+#define ZERO_PAGE(vaddr) (empty_zero_page) -+ -+#define pte_pfn(pte) (pte_val(pte) >> PAGE_SHIFT) -+#define pfn_pte(pfn,prot) (__pte(((pfn) << PAGE_SHIFT) | pgprot_val(prot))) -+ -+#define pte_none(pte) !(pte_val(pte)) -+#define pte_clear(mm,addr,ptep) set_pte_at((mm),(addr),(ptep), __pte(0)) -+#define pte_page(pte) (pfn_to_page(pte_pfn(pte))) -+ -+#define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1)) -+#define pte_offset_kernel(dir, address) ((pte_t *)pmd_page_kernel(*(dir)) + pte_index(address)) -+#define pte_offset_map(dir, address) ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address)) -+#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address) -+#define pmd_page_kernel(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK)) -+ -+#define pte_unmap(pte) do { } while (0) -+#define pte_unmap_nested(pte) do { } while (0) -+ -+#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval) -+ -+static inline pgd_t *get_pgd( void){ -+ -+ return ( pgd_t *)phys_to_virt( GET_L1_PPTB() & L1_PPTB_mskBASE); -+} -+ -+static inline void set_pgd( pgd_t *pgdp, pgd_t pgd){ -+ -+ /* TODO */ -+} -+/* -+ * Set a level 1 translation table entry, and clean it out of -+ * any caches such that the MMUs can load it correctly. -+ */ -+static inline void set_pmd( pmd_t *pmdp, pmd_t pmd){ -+ -+ *pmdp = pmd; -+#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) -+ __asm__ volatile ( "\n\tcctl %0, L1D_VA_WB" ::"r" ( pmdp) :"memory"); -+ MSYNC( all); -+ DSB(); -+#endif -+} -+ -+/* -+ * Set a PTE and flush it out -+ */ -+static inline void set_pte( pte_t *ptep, pte_t pte){ -+ -+ *ptep = pte; -+#if !defined(CONFIG_CPU_DCACHE_DISABLE) && !defined(CONFIG_CPU_DCACHE_WRITETHROUGH) -+ __asm__ volatile ( "\n\tcctl %0, L1D_VA_WB" ::"r" ( ptep) :"memory"); -+ MSYNC( all); -+ DSB(); -+#endif -+} -+ -+ -+/* -+ * The following only work if pte_present() is true. -+ * Undefined behaviour if not.. -+ */ -+ -+/* -+ * pte_write: this page is writeable for user mode -+ * pte_read: this page is readable for user mode -+ * pte_kernel_write: this page is writeable for kernel mode -+ * -+ * We don't have pte_kernel_read because kernel always can read. -+ * -+ * */ -+ -+#define pte_present(pte) (pte_val(pte) & _PAGE_V) -+#define pte_write(pte) ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) -+#define pte_read(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KR) || \ -+ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ -+ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW)) -+#define pte_kernel_write(pte) (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_URW_KRW) || \ -+ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_UR_KRW) || \ -+ ((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_KRW) || \ -+ (((pte_val(pte) & _PAGE_M_MASK) == _PAGE_M_XKRW) && pte_exec(pte))) -+#define pte_exec(pte) (pte_val(pte) & _PAGE_E) -+#define pte_dirty(pte) (pte_val(pte) & _PAGE_D) -+#define pte_young(pte) (pte_val(pte) & _PAGE_YOUNG) -+ -+/* -+ * The following only works if pte_present() is not true. -+ */ -+#define pte_file(pte) (pte_val(pte) & _PAGE_FILE) -+#define pte_to_pgoff(x) (pte_val(x) >> 2) -+#define pgoff_to_pte(x) __pte(((x) << 2) | _PAGE_FILE) -+ -+#define PTE_FILE_MAX_BITS 29 -+ -+#define PTE_BIT_FUNC(fn,op) \ -+static inline pte_t pte_##fn(pte_t pte) { pte_val(pte) op; return pte; } -+ -+static inline pte_t pte_wrprotect(pte_t pte) -+{ -+ pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; -+ pte_val(pte) = pte_val(pte) | _PAGE_M_UR_KR; -+ return pte; -+} -+ -+static inline pte_t pte_mkwrite(pte_t pte) -+{ -+ pte_val(pte) = pte_val(pte) & ~_PAGE_M_MASK; -+ pte_val(pte) = pte_val(pte) | _PAGE_M_URW_KRW; -+ return pte; -+} -+ -+PTE_BIT_FUNC(exprotect, &= ~_PAGE_E); -+PTE_BIT_FUNC(mkexec, |= _PAGE_E); -+PTE_BIT_FUNC(mkclean, &= ~_PAGE_D); -+PTE_BIT_FUNC(mkdirty, |= _PAGE_D); -+PTE_BIT_FUNC(mkold, &= ~_PAGE_YOUNG); -+PTE_BIT_FUNC(mkyoung, |= _PAGE_YOUNG); -+static inline int pte_special(pte_t pte) { return 0; } -+static inline pte_t pte_mkspecial(pte_t pte) { return pte; } -+ -+/* -+ * Mark the prot value as uncacheable and unbufferable. -+ */ -+#define pgprot_noncached(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV) -+#define pgprot_writecombine(prot) __pgprot((pgprot_val(prot)&~_PAGE_C_MASK) | _PAGE_C_DEV_WB) -+ -+#define pmd_none(pmd) (pmd_val(pmd)&0x1) -+#define pmd_present(pmd) (!pmd_none(pmd)) -+#define pmd_bad(pmd) pmd_none(pmd) -+ -+#define copy_pmd(pmdpd,pmdps) set_pmd((pmdpd), *(pmdps)) -+#define pmd_clear(pmdp) set_pmd((pmdp), __pmd(1)) -+ -+static inline pmd_t __mk_pmd(pte_t *ptep, unsigned long prot) -+{ -+ unsigned long ptr = (unsigned long)ptep; -+ pmd_t pmd; -+ -+ /* -+ * The pmd must be loaded with the physical -+ * address of the PTE table -+ */ -+ -+ pmd_val(pmd) = __virt_to_phys(ptr) | prot; -+ return pmd; -+} -+ -+ -+#define pmd_page(pmd) virt_to_page(__va(pmd_val(pmd))) -+ -+/* -+ * Permanent address of a page. We never have highmem, so this is trivial. -+ */ -+#define pages_to_mb(x) ((x) >> (20 - PAGE_SHIFT)) -+ -+/* -+ * Conversion functions: convert a page and protection to a page entry, -+ * and a page entry and page directory to the page they refer to. -+ */ -+#define mk_pte(page,prot) pfn_pte(page_to_pfn(page),prot) -+ -+/* -+ * The "pgd_xxx()" functions here are trivial for a folded two-level -+ * setup: the pgd is never bad, and a pmd always exists (as it's folded -+ * into the pgd entry) -+ */ -+#define pgd_none(pgd) (0) -+#define pgd_bad(pgd) (0) -+#define pgd_present(pgd) (1) -+#define pgd_clear(pgdp) do { } while (0) -+ -+#define page_pte_prot(page,prot) mk_pte(page, prot) -+#define page_pte(page) mk_pte(page, __pgprot(0)) -+/* Tom: -+ * L1PTE = $mr1 + ((virt >> PMD_SHIFT) << 2); -+ * L2PTE = (((virt >> PAGE_SHIFT) & (PTRS_PER_PTE -1 )) << 2); -+ * PPN = (phys & 0xfffff000); -+ * -+*/ -+ -+/* to find an entry in a page-table-directory */ -+#define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD - 1)) -+#define pgd_offset(mm, address) ((mm)->pgd + pgd_index(address)) -+/* to find an entry in a kernel page-table-directory */ -+#define pgd_offset_k(addr) pgd_offset(&init_mm, addr) -+ -+/* Find an entry in the second-level page table.. */ -+#define pmd_offset(dir, addr) ((pmd_t *)(dir)) -+ -+static inline pte_t pte_modify(pte_t pte, pgprot_t newprot) -+{ -+ const unsigned long mask = 0xfff; -+ pte_val(pte) = (pte_val(pte) & ~mask) | (pgprot_val(newprot) & mask); -+ return pte; -+} -+ -+extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -+ -+/* Encode and decode a swap entry. -+ * -+ * We support up to 32GB of swap on 4k machines -+ */ -+#define __swp_type(x) (((x).val >> 2) & 0x7f) -+#define __swp_offset(x) ((x).val >> 9) -+#define __swp_entry(type,offset) ((swp_entry_t) { ((type) << 2) | ((offset) << 9) }) -+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) }) -+#define __swp_entry_to_pte(swp) ((pte_t) { (swp).val }) -+ -+/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ -+/* FIXME: this is not correct */ -+#define kern_addr_valid(addr) (1) -+ -+#include -+ -+/* -+ * We provide our own arch_get_unmapped_area to cope with VIPT caches. -+ */ -+#define HAVE_ARCH_UNMAPPED_AREA -+ -+/* -+ * remap a physical address `phys' of size `size' with page protection `prot' -+ * into virtual address `from' -+ */ -+#define io_remap_pfn_range(vma,from,pfn,size,prot) \ -+ remap_pfn_range(vma, from, pfn, size, prot) -+ -+#define pgtable_cache_init() do { } while (0) -+ -+#endif /* !__ASSEMBLY__ */ -+ -+#endif /* _ASMNDS32_PGTABLE_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/poll.h linux-3.4.113/arch/nds32/include/asm/poll.h ---- linux-3.4.113.orig/arch/nds32/include/asm/poll.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/poll.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/poll.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASMNDS32_POLL_H -+#define __ASMNDS32_POLL_H -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/posix_types.h linux-3.4.113/arch/nds32/include/asm/posix_types.h ---- linux-3.4.113.orig/arch/nds32/include/asm/posix_types.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/posix_types.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,40 @@ -+/* -+ * arch/arm/include/asm/posix_types.h -+ * -+ * Copyright (C) 1996-1998 Russell King. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Changelog: -+ * 27-06-1996 RMK Created -+ */ -+#ifndef __ARCH_NDS32_POSIX_TYPES_H -+#define __ARCH_NDS32_POSIX_TYPES_H -+ -+/* -+ * This file is generally used by user-level software, so you need to -+ * be a little careful about namespace pollution etc. Also, we cannot -+ * assume GCC is being used. -+ */ -+ -+typedef unsigned short __kernel_mode_t; -+#define __kernel_mode_t __kernel_mode_t -+ -+typedef unsigned short __kernel_nlink_t; -+#define __kernel_nlink_t __kernel_nlink_t -+ -+typedef unsigned short __kernel_ipc_pid_t; -+#define __kernel_ipc_pid_t __kernel_ipc_pid_t -+ -+typedef unsigned short __kernel_uid_t; -+typedef unsigned short __kernel_gid_t; -+#define __kernel_uid_t __kernel_uid_t -+ -+typedef unsigned short __kernel_old_dev_t; -+#define __kernel_old_dev_t __kernel_old_dev_t -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/processor.h linux-3.4.113/arch/nds32/include/asm/processor.h ---- linux-3.4.113.orig/arch/nds32/include/asm/processor.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/processor.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,133 @@ -+/* -+ * linux/arch/nds32/include/asm/processor.h -+ */ -+/* Copyright (C) 1995-1999 Russell King -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/* ============================================================================ -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is ptrace relative code for Andes NDS32 architecture. -+ * Original referred from ARM, fit to NDS32. -+ * -+ * Revision History: -+ * -+ * Oct.03.2007 Original from Tom, Shawn and Steven, refined by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#ifndef __ASM_NDS32_PROCESSOR_H -+#define __ASM_NDS32_PROCESSOR_H -+ -+/* -+ * Default implementation of macro that returns current -+ * instruction pointer ("program counter"). -+ */ -+#define current_text_addr() ({ __label__ _l; _l: &&_l;}) -+ -+#ifdef __KERNEL__ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define KERNEL_STACK_SIZE PAGE_SIZE -+#define STACK_TOP TASK_SIZE -+#define STACK_TOP_MAX TASK_SIZE -+ -+struct debug_info { -+ u32 address; -+ u16 insn; -+ u8 valid; -+}; -+ -+struct thread_struct { -+ /* fault info */ -+ unsigned long address; -+ unsigned long trap_no; -+ unsigned long error_code; -+ -+ struct fpu_struct fpu; /* Saved fpu/fpu emulator stuff. */ -+ struct audio_struct audio; -+ struct debug_info debug; /* debugging */ -+}; -+ -+#define INIT_THREAD { } -+ -+#ifdef __NDS32_EB__ -+#define PSW_DE PSW_mskBE -+#else -+#define PSW_DE 0x0 -+#endif -+ -+#ifdef CONFIG_WBNA -+#define PSW_valWBNA PSW_mskWBNA -+#else -+#define PSW_valWBNA 0x0 -+#endif -+ -+#define start_thread(regs,pc,sp) \ -+({ \ -+ unsigned long *stack = (unsigned long *)sp; \ -+ set_fs(USER_DS); \ -+ memzero(regs->uregs, sizeof(regs->uregs)); \ -+ regs->NDS32_ipsw = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_mskGIE); \ -+ regs->NDS32_ir0 = (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | PSW_SYSTEM | PSW_INTL_1); \ -+ regs->NDS32_ipc = pc; /* pc */ \ -+ regs->NDS32_sp = sp; /* $sp */ \ -+ regs->NDS32_r2 = stack[4]; /* $r2 (envp) */ \ -+ regs->NDS32_r1 = stack[1]; /* $r1 (argv) */ \ -+ regs->NDS32_r0 = stack[0]; /* $r0 (argc) */ \ -+}) -+ -+ -+/* Forward declaration, a strange C thing */ -+struct task_struct; -+ -+/* Free all resources held by a thread. */ -+extern void release_thread(struct task_struct *); -+#ifdef CONFIG_FPU -+#ifndef CONFIG_UNLAZU_FPU //lazy fpu -+extern struct task_struct *last_task_used_math; -+#endif -+#endif -+#ifdef CONFIG_AUDIO -+#ifndef CONFIG_UNLAZY_AUDIO //lazy audio -+extern struct task_struct *last_task_used_audio; -+#endif -+#endif -+ -+/* Prepare to copy thread state - unlazy all lazy status */ -+#define prepare_to_copy(tsk) do { } while (0) -+ -+unsigned long get_wchan(struct task_struct *p); -+ -+#define cpu_relax() barrier() -+ -+#define task_pt_regs(task) \ -+ ((struct pt_regs *) (task_stack_page(task) + THREAD_SIZE \ -+ - 8) - 1) -+ -+/* -+ * Create a new kernel thread -+ */ -+extern int kernel_thread(int (*fn)(void *), void *arg, unsigned long flags); -+ -+#define KSTK_EIP(tsk) (((unsigned long *)(4096+(unsigned long)task_thread_info(tsk)))[1019]) -+#define KSTK_ESP(tsk) (((unsigned long *)(4096+(unsigned long)task_thread_info(tsk)))[1017]) -+ -+ -+#endif -+ -+#endif /* __ASM_NDS32_PROCESSOR_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/proc-fns.h linux-3.4.113/arch/nds32/include/asm/proc-fns.h ---- linux-3.4.113.orig/arch/nds32/include/asm/proc-fns.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/proc-fns.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,88 @@ -+/* -+ * linux/arch/nds32/include/asm/proc-fns.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_PROCFNS_H__ -+#define __NDS32_PROCFNS_H__ -+ -+#define CPU_NAME n12 -+ -+#ifdef __KERNEL__ -+ -+#ifdef __STDC__ -+#define ____cpu_fn(name,fn) name##fn -+#else -+#define ____cpu_fn(name,fn) name/**/fn -+#endif -+#define __cpu_fn(name,fn) ____cpu_fn(name,fn) -+ -+#define cpu_proc_init __cpu_fn( CPU_NAME, _proc_init) -+#define cpu_proc_fin __cpu_fn( CPU_NAME, _proc_fin) -+#define cpu_do_idle __cpu_fn( CPU_NAME, _do_idle) -+#define cpu_reset __cpu_fn( CPU_NAME, _reset) -+#define cpu_switch_mm __cpu_fn( CPU_NAME, _switch_mm) -+ -+#define cpu_dcache_inval_all __cpu_fn( CPU_NAME, _dcache_inval_all) -+#define cpu_dcache_wbinval_all __cpu_fn( CPU_NAME, _dcache_wbinval_all) -+#define cpu_dcache_inval_page __cpu_fn( CPU_NAME, _dcache_inval_page) -+#define cpu_dcache_wb_page __cpu_fn( CPU_NAME, _dcache_wb_page) -+#define cpu_dcache_wbinval_page __cpu_fn( CPU_NAME, _dcache_wbinval_page) -+#define cpu_dcache_inval_range __cpu_fn( CPU_NAME, _dcache_inval_range) -+#define cpu_dcache_wb_range __cpu_fn( CPU_NAME, _dcache_wb_range) -+#define cpu_dcache_wbinval_range __cpu_fn( CPU_NAME, _dcache_wbinval_range) -+ -+#define cpu_icache_inval_all __cpu_fn( CPU_NAME, _icache_inval_all) -+#define cpu_icache_inval_page __cpu_fn( CPU_NAME, _icache_inval_page) -+#define cpu_icache_inval_range __cpu_fn( CPU_NAME, _icache_inval_range) -+ -+#define cpu_cache_wbinval_page __cpu_fn( CPU_NAME, _cache_wbinval_page) -+#define cpu_cache_wbinval_range __cpu_fn( CPU_NAME, _cache_wbinval_range) -+#define cpu_cache_wbinval_range_check __cpu_fn( CPU_NAME, _cache_wbinval_range_check) -+ -+#define cpu_dma_wb_range __cpu_fn( CPU_NAME, _dma_wb_range) -+#define cpu_dma_inval_range __cpu_fn( CPU_NAME, _dma_inval_range) -+#define cpu_dma_wbinval_range __cpu_fn( CPU_NAME, _dma_wbinval_range) -+ -+#include -+ -+struct mm_struct; -+struct vm_area_struct; -+extern void cpu_proc_init(void); -+extern void cpu_proc_fin(void); -+extern void cpu_do_idle(void); -+extern void cpu_reset(unsigned long reset); -+extern void cpu_switch_mm(struct mm_struct *mm); -+ -+extern void cpu_dcache_inval_all(void); -+extern void cpu_dcache_wbinval_all(void); -+extern void cpu_dcache_inval_page(unsigned long page); -+extern void cpu_dcache_wb_page(unsigned long page); -+extern void cpu_dcache_wbinval_page(unsigned long page); -+extern void cpu_dcache_inval_range(unsigned long start, unsigned long end); -+extern void cpu_dcache_wb_range(unsigned long start, unsigned long end); -+extern void cpu_dcache_wbinval_range(unsigned long start, unsigned long end); -+ -+extern void cpu_icache_inval_all(void); -+extern void cpu_icache_inval_page(unsigned long page); -+extern void cpu_icache_inval_range(unsigned long start, unsigned long end); -+ -+extern void cpu_cache_wbinval_page(unsigned long page, int flushi); -+extern void cpu_cache_wbinval_range(unsigned long start, -+ unsigned long end, int flushi); -+extern void cpu_cache_wbinval_range_check(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end); -+ -+extern void cpu_dma_wb_range(unsigned long start, unsigned long end); -+extern void cpu_dma_inval_range(unsigned long start, unsigned long end); -+extern void cpu_dma_wbinval_range(unsigned long start, unsigned long end); -+ -+#ifdef CONFIG_CACHE_L2 -+#define cpu_L2cache_inval __cpu_fn(CPU_NAME, _L2cache_inval) -+#define cpu_L2cache_wb __cpu_fn(CPU_NAME, _L2cache_wb) -+extern void cpu_L2cache_inval(void); -+extern void cpu_L2cache_wb(void); -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __NDS32_PROCFNS_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/procinfo.h linux-3.4.113/arch/nds32/include/asm/procinfo.h ---- linux-3.4.113.orig/arch/nds32/include/asm/procinfo.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/procinfo.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,71 @@ -+/* -+ * linux/arch/nds32/include/asm/procinfo.h -+ * -+ * Copyright (C) 1996-1999 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_PROCINFO_H -+#define __ASM_PROCINFO_H -+ -+#ifndef __ASSEMBLY__ -+ -+/* -+ * These structure are defined in assembly -+ * ( nds32/mm/proc-nds32.S) -+ */ -+struct proc_info_item { -+ -+ const char *manufacturer; -+ const char *cpu_name; -+}; -+ -+/* -+ * Note! struct processor is always defined if we're -+ * using MULTI_CPU, otherwise this entry is unused, -+ * but still exists. -+ * -+ * NOTE! The following structure is defined by assembly -+ * language, NOT C code. For more information, check: -+ * arch/arm/mm/proc-*.S and arch/arm/kernel/head.S -+ */ -+struct proc_info_list { -+ -+ unsigned int cpu_val; -+ unsigned int cpu_mask; -+ const char *arch_name; -+ const char *elf_name; -+ unsigned int elf_hwcap; -+ struct proc_info_item *info; -+}; -+ -+extern unsigned int elf_hwcap; -+ -+#endif /* __ASSEMBLY__ */ -+ -+#define HWCAP_MFUSR_PC 0x000001 -+#define HWCAP_EXT 0x000002 -+#define HWCAP_EXT2 0x000004 -+#define HWCAP_FPU 0x000008 -+#define HWCAP_AUDIO 0x000010 -+#define HWCAP_BASE16 0x000020 -+#define HWCAP_STRING 0x000040 -+#define HWCAP_REDUCED_REGS 0x000080 -+#define HWCAP_VIDEO 0x000100 -+#define HWCAP_ENCRYPT 0x000200 -+#define HWCAP_EDM 0x000400 -+#define HWCAP_LMDMA 0x000800 -+#define HWCAP_PFM 0x001000 -+#define HWCAP_HSMP 0x002000 -+#define HWCAP_TRACE 0x004000 -+#define HWCAP_DIV 0x008000 -+#define HWCAP_MAC 0x010000 -+#define HWCAP_L2C 0x020000 -+#define HWCAP_FPU_DP 0x040000 -+#define HWCAP_V2 0x080000 -+#define HWCAP_DX_REGS 0x100000 -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ptrace.h linux-3.4.113/arch/nds32/include/asm/ptrace.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ptrace.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ptrace.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,119 @@ -+/* -+ * linux/arch/nds32/include/asm/ptrace.h -+ * -+ * Copyright (C) 1996-2003 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_NDS32_PTRACE_H -+#define __ASM_NDS32_PTRACE_H -+ -+#define PTRACE_GETREGS 12 -+#define PTRACE_SETREGS 13 -+#define PTRACE_GETFPREGS 14 -+#define PTRACE_SETFPREGS 15 -+#define PTRACE_GETAUREGS 18 -+#define PTRACE_SETAUREGS 19 -+ -+#define PTRACE_OLDSETOPTIONS 21 -+ -+#define PTRACE_GET_THREAD_AREA 22 -+ -+#ifndef __ASSEMBLY__ -+/* this struct defines the way the registers are stored on the -+ stack during a system call. */ -+ -+struct pt_regs { -+#if defined(CONFIG_ABI1) -+ long dummy[6]; -+#endif -+ long uregs[44]; -+}; -+#define NDS32_osp uregs[43] -+#define NDS32_FUCOP_CTL uregs[42] -+#define NDS32_lp uregs[41] -+#define NDS32_gp uregs[40] -+#define NDS32_fp uregs[39] -+#define NDS32_r25 uregs[38] -+#define NDS32_r24 uregs[37] -+#define NDS32_r23 uregs[36] -+#define NDS32_r22 uregs[35] -+#define NDS32_r21 uregs[34] -+#define NDS32_r20 uregs[33] -+#define NDS32_r19 uregs[32] -+#define NDS32_r18 uregs[31] -+#define NDS32_r17 uregs[30] -+#define NDS32_r16 uregs[29] -+#define NDS32_r15 uregs[28] -+#define NDS32_r14 uregs[27] -+#define NDS32_r13 uregs[26] -+#define NDS32_r12 uregs[25] -+#define NDS32_r11 uregs[24] -+#define NDS32_r10 uregs[23] -+#define NDS32_r9 uregs[22] -+#define NDS32_r8 uregs[21] -+#define NDS32_r7 uregs[20] -+#define NDS32_r6 uregs[19] -+#define NDS32_r5 uregs[18] -+#define NDS32_r4 uregs[17] -+#define NDS32_r3 uregs[16] -+#define NDS32_r2 uregs[15] -+#define NDS32_r1 uregs[14] -+#define NDS32_r0 uregs[13] -+#if defined(CONFIG_HWZOL) -+#define NDS32_lc uregs[11] -+#define NDS32_le uregs[10] -+#define NDS32_lb uregs[9] -+#endif -+#define NDS32_pp1 uregs[8] -+#define NDS32_pp0 uregs[7] -+#define NDS32_pipc uregs[6] -+#define NDS32_pipsw uregs[5] -+#define NDS32_ORIG_r0 uregs[4] -+#define NDS32_sp uregs[3] -+#define NDS32_ipc uregs[2] -+#define NDS32_ipsw uregs[1] -+#define NDS32_ir0 uregs[0] -+ -+#ifdef __KERNEL__ -+#include -+ -+#define arch_has_single_step() (1) -+struct task_struct; -+extern void user_enable_single_step(struct task_struct *); -+extern void user_disable_single_step(struct task_struct *); -+ -+#define user_mode(regs) (((regs)->NDS32_ipsw & PSW_mskPOM) == 0) -+ -+#define interrupts_enabled(regs) (!((regs)->NDS32_ipsw & ~PSW_mskGIE)) -+ -+extern void show_regs(struct pt_regs *); -+ -+/* Are the current registers suitable for user mode? -+ * (used to maintain security in signal handlers) -+ */ -+static inline int valid_user_regs(struct pt_regs *regs) -+{ -+ return user_mode(regs) && ((regs->NDS32_ipsw & PSW_mskGIE) == 1); -+} -+ -+static inline unsigned long regs_return_value(struct pt_regs *regs) -+{ -+ return regs->NDS32_r0; -+} -+ -+ -+#define instruction_pointer(regs) ((regs)->NDS32_ipc) -+ -+#ifdef CONFIG_SMP -+extern unsigned long profile_pc(struct pt_regs *regs); -+#else -+#define profile_pc(regs) instruction_pointer(regs) -+#endif -+ -+#endif /* __KERNEL__ */ -+#endif /* __ASSEMBLY__ */ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/reg_access.h linux-3.4.113/arch/nds32/include/asm/reg_access.h ---- linux-3.4.113.orig/arch/nds32/include/asm/reg_access.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/reg_access.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,153 @@ -+/* -+ * linux/arch/nds32/include/asm/reg_access.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_REG_ACCESS_H__ -+#define __NDS32_REG_ACCESS_H__ -+ -+#ifndef __ASSEMBLY__ -+#define DEFINE_GET_SYS_REG( reg) \ -+inline static unsigned long GET_##reg( void){ \ -+ unsigned long val; \ -+ __asm__ volatile ( "mfsr %0, $"#reg :"=&r" (val) ::"memory"); \ -+ return val; \ -+} -+ -+#define DEFINE_PUT_SYS_REG( reg) \ -+inline static void SET_##reg( unsigned long val){ \ -+ __asm__ volatile ( "\n\tmtsr %0, $"#reg \ -+ "\n\tdsb" ::"r" ( val) :"memory"); \ -+} -+ -+#define DEFINE_PUT_SYS_REG_i( reg) \ -+inline static void SET_##reg( unsigned long val){ \ -+ __asm__ volatile ( "\n\tmtsr %0, $"#reg \ -+ "\n\tisb" ::"r" ( val) :"memory"); \ -+} -+#define DEFINE_SYS_REG_OP( reg) \ -+DEFINE_GET_SYS_REG( reg); \ -+DEFINE_PUT_SYS_REG( reg); -+ -+#define DEFINE_SYS_REG_OP_i( reg) \ -+DEFINE_GET_SYS_REG( reg); \ -+DEFINE_PUT_SYS_REG_i( reg); -+ -+DEFINE_SYS_REG_OP( CPU_VER); -+DEFINE_SYS_REG_OP( ICM_CFG); -+DEFINE_SYS_REG_OP( DCM_CFG); -+DEFINE_SYS_REG_OP( MMU_CFG); -+DEFINE_SYS_REG_OP( MSC_CFG); -+DEFINE_SYS_REG_OP( CORE_ID); -+DEFINE_SYS_REG_OP( FUCOP_EXIST); -+ -+DEFINE_SYS_REG_OP_i( PSW); -+DEFINE_SYS_REG_OP( IPSW); -+DEFINE_SYS_REG_OP( P_IPSW); -+DEFINE_SYS_REG_OP( IVB); -+DEFINE_SYS_REG_OP( EVA); -+DEFINE_SYS_REG_OP( P_EVA); -+DEFINE_SYS_REG_OP( ITYPE); -+DEFINE_SYS_REG_OP( P_ITYPE); -+DEFINE_SYS_REG_OP( MERR); -+DEFINE_SYS_REG_OP( IPC); -+DEFINE_SYS_REG_OP( P_IPC); -+DEFINE_SYS_REG_OP( OIPC); -+DEFINE_SYS_REG_OP( P_P0); -+DEFINE_SYS_REG_OP( P_P1); -+DEFINE_SYS_REG_OP( INT_MASK); -+DEFINE_SYS_REG_OP( INT_PEND); -+DEFINE_SYS_REG_OP( INT_MASK2); -+DEFINE_SYS_REG_OP( INT_PEND2); -+DEFINE_SYS_REG_OP( INT_TRIGGER); -+ -+DEFINE_SYS_REG_OP( MMU_CTL); -+DEFINE_SYS_REG_OP( L1_PPTB); -+DEFINE_SYS_REG_OP( TLB_VPN); -+DEFINE_SYS_REG_OP( TLB_DATA); -+DEFINE_SYS_REG_OP( TLB_MISC); -+DEFINE_SYS_REG_OP( VLPT_IDX); -+DEFINE_SYS_REG_OP( ILMB); -+DEFINE_SYS_REG_OP( DLMB); -+DEFINE_SYS_REG_OP( CACHE_CTL); -+DEFINE_SYS_REG_OP( HSMP_SADDR); -+DEFINE_SYS_REG_OP( HSMP_EADDR); -+ -+DEFINE_SYS_REG_OP( EDM_CFG); -+DEFINE_SYS_REG_OP( EDMSW); -+DEFINE_SYS_REG_OP( EDM_CTL); -+DEFINE_SYS_REG_OP( EDM_DTR); -+DEFINE_SYS_REG_OP( BPMTC); -+DEFINE_SYS_REG_OP( DIMBR); -+DEFINE_SYS_REG_OP( TECR0); -+DEFINE_SYS_REG_OP( TECR1); -+ -+DEFINE_SYS_REG_OP( BPC0); -+DEFINE_SYS_REG_OP( BPA0); -+DEFINE_SYS_REG_OP( BPAM0); -+DEFINE_SYS_REG_OP( BPV0); -+DEFINE_SYS_REG_OP( BPCID0); -+DEFINE_SYS_REG_OP( BPC1); -+DEFINE_SYS_REG_OP( BPA1); -+DEFINE_SYS_REG_OP( BPAM1); -+DEFINE_SYS_REG_OP( BPV1); -+DEFINE_SYS_REG_OP( BPCID1); -+DEFINE_SYS_REG_OP( BPC2); -+DEFINE_SYS_REG_OP( BPA2); -+DEFINE_SYS_REG_OP( BPAM2); -+DEFINE_SYS_REG_OP( BPV2); -+DEFINE_SYS_REG_OP( BPCID2); -+DEFINE_SYS_REG_OP( BPC3); -+DEFINE_SYS_REG_OP( BPA3); -+DEFINE_SYS_REG_OP( BPAM3); -+DEFINE_SYS_REG_OP( BPV3); -+DEFINE_SYS_REG_OP( BPCID3); -+DEFINE_SYS_REG_OP( BPC4); -+DEFINE_SYS_REG_OP( BPA4); -+DEFINE_SYS_REG_OP( BPAM4); -+DEFINE_SYS_REG_OP( BPV4); -+DEFINE_SYS_REG_OP( BPCID4); -+DEFINE_SYS_REG_OP( BPC5); -+DEFINE_SYS_REG_OP( BPA5); -+DEFINE_SYS_REG_OP( BPAM5); -+DEFINE_SYS_REG_OP( BPV5); -+DEFINE_SYS_REG_OP( BPCID5); -+DEFINE_SYS_REG_OP( BPC6); -+DEFINE_SYS_REG_OP( BPA6); -+DEFINE_SYS_REG_OP( BPAM6); -+DEFINE_SYS_REG_OP( BPV6); -+DEFINE_SYS_REG_OP( BPCID6); -+DEFINE_SYS_REG_OP( BPC7); -+DEFINE_SYS_REG_OP( BPA7); -+DEFINE_SYS_REG_OP( BPAM7); -+DEFINE_SYS_REG_OP( BPV7); -+DEFINE_SYS_REG_OP( BPCID7); -+ -+DEFINE_SYS_REG_OP( PFMC0); -+DEFINE_SYS_REG_OP( PFMC1); -+DEFINE_SYS_REG_OP( PFMC2); -+DEFINE_SYS_REG_OP( PFM_CTL); -+ -+DEFINE_SYS_REG_OP( SDZ_CTL); -+DEFINE_SYS_REG_OP( N12MISC_CTL); -+DEFINE_SYS_REG_OP( PRUSR_ACC_CTL); -+ -+DEFINE_SYS_REG_OP( DMA_CFG); -+DEFINE_SYS_REG_OP( DMA_GCSW); -+DEFINE_SYS_REG_OP( DMA_CHNSEL); -+DEFINE_SYS_REG_OP( DMA_ACT); -+DEFINE_SYS_REG_OP( DMA_SETUP); -+DEFINE_SYS_REG_OP( DMA_ISADDR); -+DEFINE_SYS_REG_OP( DMA_ESADDR); -+DEFINE_SYS_REG_OP( DMA_TCNT); -+DEFINE_SYS_REG_OP( DMA_STATUS); -+DEFINE_SYS_REG_OP( DMA_2DSET); -+DEFINE_SYS_REG_OP( DMA_2DSCTL); -+ -+DEFINE_SYS_REG_OP( FPCSR); -+DEFINE_SYS_REG_OP( FPCFG); -+DEFINE_SYS_REG_OP( FUCOP_CTL); -+ -+#endif /* !__ASSEMBLY__ */ -+ -+#endif /* __NDS32_REG_ACCESS_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/resource.h linux-3.4.113/arch/nds32/include/asm/resource.h ---- linux-3.4.113.orig/arch/nds32/include/asm/resource.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/resource.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/resource.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_RESOURCE_H__ -+#define __NDS32_RESOURCE_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/rtc.h linux-3.4.113/arch/nds32/include/asm/rtc.h ---- linux-3.4.113.orig/arch/nds32/include/asm/rtc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/rtc.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,43 @@ -+/* -+ * linux/arch/nds32/include/asm/rtc.h -+ * -+ * Copyright (C) 2003 Deep Blue Solutions Ltd. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef ASMNDS32_RTC_H -+#define ASMNDS32_RTC_H -+ -+struct module; -+ -+struct rtc_ops { -+ struct module *owner; -+ int (*open)(void); -+ void (*release)(void); -+ int (*ioctl)(unsigned int, unsigned long); -+ -+ int (*read_time)(struct rtc_time *); -+ int (*set_time)(struct rtc_time *); -+ int (*read_alarm)(struct rtc_wkalrm *); -+ int (*set_alarm)(struct rtc_wkalrm *); -+ int (*proc)(char *buf); -+}; -+ -+void rtc_update(unsigned long, unsigned long); -+int register_rtc(struct rtc_ops *); -+void unregister_rtc(struct rtc_ops *); -+ -+static inline int rtc_periodic_alarm(struct rtc_time *tm) -+{ -+ return (tm->tm_year == -1) || -+ ((unsigned)tm->tm_mon >= 12) || -+ ((unsigned)(tm->tm_mday - 1) >= 31) || -+ ((unsigned)tm->tm_hour > 23) || -+ ((unsigned)tm->tm_min > 59) || -+ ((unsigned)tm->tm_sec > 59); -+} -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/scatterlist.h linux-3.4.113/arch/nds32/include/asm/scatterlist.h ---- linux-3.4.113.orig/arch/nds32/include/asm/scatterlist.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/scatterlist.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,35 @@ -+/* -+ * linux/arch/nds32/include/asm/scatterlist.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SCATTERLIST_H -+#define _ASMNDS32_SCATTERLIST_H -+ -+#include -+#include -+#include -+ -+#if 0 -+struct scatterlist { -+#ifdef CONFIG_DEBUG_SG -+ unsigned long sg_magic; -+#endif -+ unsigned long page_link; -+ unsigned int offset; /* buffer offset */ -+ dma_addr_t dma_address; /* dma address */ -+ unsigned int length; /* length */ -+}; -+ -+/* -+ * These macros should be used after a pci_map_sg call has been done -+ * to get bus addresses of each of the SG entries and their lengths. -+ * You should only work with the number of sg entries pci_map_sg -+ * returns, or alternatively stop on the first sg_dma_len(sg) which -+ * is 0. -+ */ -+#define sg_dma_address(sg) ((sg)->dma_address) -+#define sg_dma_len(sg) ((sg)->length) -+#endif -+ -+#endif /* _ASMNDS32_SCATTERLIST_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/sections.h linux-3.4.113/arch/nds32/include/asm/sections.h ---- linux-3.4.113.orig/arch/nds32/include/asm/sections.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/sections.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/sections.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __NDS32_SECTIONS_H__ -+#define __NDS32_SECTIONS_H__ -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/segment.h linux-3.4.113/arch/nds32/include/asm/segment.h ---- linux-3.4.113.orig/arch/nds32/include/asm/segment.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/segment.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,16 @@ -+/* -+ * linux/arch/nds32/include/asm/segment.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_SEGMENT_H -+#define __ASM_NDS32_SEGMENT_H -+ -+#define __KERNEL_CS 0x0 -+#define __KERNEL_DS 0x0 -+ -+#define __USER_CS 0x1 -+#define __USER_DS 0x1 -+ -+#endif /* __ASM_NDS32_SEGMENT_H */ -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/semaphore.h linux-3.4.113/arch/nds32/include/asm/semaphore.h ---- linux-3.4.113.orig/arch/nds32/include/asm/semaphore.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/semaphore.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,6 @@ -+/* -+ * linux/arch/nds32/include/asm/semaphore.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#include -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/semaphore-helper.h linux-3.4.113/arch/nds32/include/asm/semaphore-helper.h ---- linux-3.4.113.orig/arch/nds32/include/asm/semaphore-helper.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/semaphore-helper.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,89 @@ -+/* -+ * linux/arch/nds32/include/asm/semaphore-helper.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef ASMNDS32_SEMAPHORE_HELPER_H -+#define ASMNDS32_SEMAPHORE_HELPER_H -+ -+/* -+ * These two _must_ execute atomically wrt each other. -+ */ -+static inline void wake_one_more(struct semaphore * sem) -+{ -+ unsigned long flags; -+ -+ spin_lock_irqsave(&semaphore_wake_lock, flags); -+ if (atomic_read(&sem->count) <= 0) -+ sem->waking++; -+ spin_unlock_irqrestore(&semaphore_wake_lock, flags); -+} -+ -+static inline int waking_non_zero(struct semaphore *sem) -+{ -+ unsigned long flags; -+ int ret = 0; -+ -+ spin_lock_irqsave(&semaphore_wake_lock, flags); -+ if (sem->waking > 0) { -+ sem->waking--; -+ ret = 1; -+ } -+ spin_unlock_irqrestore(&semaphore_wake_lock, flags); -+ return ret; -+} -+ -+/* -+ * waking non zero interruptible -+ * 1 got the lock -+ * 0 go to sleep -+ * -EINTR interrupted -+ * -+ * We must undo the sem->count down_interruptible() increment while we are -+ * protected by the spinlock in order to make this atomic_inc() with the -+ * atomic_read() in wake_one_more(), otherwise we can race. -arca -+ */ -+static inline int waking_non_zero_interruptible(struct semaphore *sem, -+ struct task_struct *tsk) -+{ -+ unsigned long flags; -+ int ret = 0; -+ -+ spin_lock_irqsave(&semaphore_wake_lock, flags); -+ if (sem->waking > 0) { -+ sem->waking--; -+ ret = 1; -+ } else if (signal_pending(tsk)) { -+ atomic_inc(&sem->count); -+ ret = -EINTR; -+ } -+ spin_unlock_irqrestore(&semaphore_wake_lock, flags); -+ return ret; -+} -+ -+/* -+ * waking_non_zero_try_lock: -+ * 1 failed to lock -+ * 0 got the lock -+ * -+ * We must undo the sem->count down_interruptible() increment while we are -+ * protected by the spinlock in order to make this atomic_inc() with the -+ * atomic_read() in wake_one_more(), otherwise we can race. -arca -+ */ -+static inline int waking_non_zero_trylock(struct semaphore *sem) -+{ -+ unsigned long flags; -+ int ret = 1; -+ -+ spin_lock_irqsave(&semaphore_wake_lock, flags); -+ if (sem->waking <= 0) -+ atomic_inc(&sem->count); -+ else { -+ sem->waking--; -+ ret = 0; -+ } -+ spin_unlock_irqrestore(&semaphore_wake_lock, flags); -+ return ret; -+} -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/sembuf.h linux-3.4.113/arch/nds32/include/asm/sembuf.h ---- linux-3.4.113.orig/arch/nds32/include/asm/sembuf.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/sembuf.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,30 @@ -+/* -+ * linux/arch/nds32/include/asm/sembuf.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SEMBUF_H -+#define _ASMNDS32_SEMBUF_H -+ -+/* -+ * The semid64_ds structure for arm architecture. -+ * Note extra padding because this structure is passed back and forth -+ * between kernel and user space. -+ * -+ * Pad space is left for: -+ * - 64-bit time_t to solve y2038 problem -+ * - 2 miscellaneous 32-bit values -+ */ -+ -+struct semid64_ds { -+ struct ipc64_perm sem_perm; /* permissions .. see ipc.h */ -+ __kernel_time_t sem_otime; /* last semop time */ -+ unsigned long __unused1; -+ __kernel_time_t sem_ctime; /* last change time */ -+ unsigned long __unused2; -+ unsigned long sem_nsems; /* no. of semaphores in array */ -+ unsigned long __unused3; -+ unsigned long __unused4; -+}; -+ -+#endif /* _ASMNDS32_SEMBUF_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/serial.h linux-3.4.113/arch/nds32/include/asm/serial.h ---- linux-3.4.113.orig/arch/nds32/include/asm/serial.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/serial.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,20 @@ -+/* -+ * linux/arch/nds32/include/asm/serial.h -+ * -+ * Copyright (C) 1996 Russell King. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Changelog: -+ * 15-10-1996 RMK Created -+ */ -+ -+#ifndef __ASM_SERIAL_H -+#define __ASM_SERIAL_H -+ -+#define BASE_BAUD (CONFIG_UART_CLK / 16) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/setup.h linux-3.4.113/arch/nds32/include/asm/setup.h ---- linux-3.4.113.orig/arch/nds32/include/asm/setup.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/setup.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,232 @@ -+/* -+ * linux/arch/nds32/include/asm/setup.h -+ * -+ * Copyright (C) 1997-1999 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Structure passed to kernel to tell it about the -+ * hardware it's running on. See Documentation/arm/Setup -+ * for more info. -+ */ -+#ifndef __ASMNDS32_SETUP_H -+#define __ASMNDS32_SETUP_H -+ -+#define COMMAND_LINE_SIZE 256 -+ -+/* The list ends with an ATAG_NONE node. */ -+#define ATAG_NONE 0x00000000 -+ -+struct tag_header { -+ u32 size; -+ u32 tag; -+}; -+ -+/* The list must start with an ATAG_CORE node */ -+#define ATAG_CORE 0x54410001 -+ -+struct tag_core { -+ u32 flags; /* bit 0 = read-only */ -+ u32 pagesize; -+ u32 rootdev; -+}; -+ -+/* it is allowed to have multiple ATAG_MEM nodes */ -+#define ATAG_MEM 0x54410002 -+ -+struct tag_mem32 { -+ u32 size; -+ u32 start; /* physical start address */ -+}; -+ -+/* VGA text type displays */ -+#define ATAG_VIDEOTEXT 0x54410003 -+ -+struct tag_videotext { -+ u8 x; -+ u8 y; -+ u16 video_page; -+ u8 video_mode; -+ u8 video_cols; -+ u16 video_ega_bx; -+ u8 video_lines; -+ u8 video_isvga; -+ u16 video_points; -+}; -+ -+/* describes how the ramdisk will be used in kernel */ -+#define ATAG_RAMDISK 0x54410004 -+ -+struct tag_ramdisk { -+ u32 flags; /* bit 0 = load, bit 1 = prompt */ -+ u32 size; /* decompressed ramdisk size in _kilo_ bytes */ -+ u32 start; /* starting block of floppy-based RAM disk image */ -+}; -+ -+/*M Tom -+ * this one accidentally used virtual addresses - as such, -+ * it's deprecated. -+ * describes where the compressed ramdisk image lives (virtual address) -+ */ -+#define ATAG_INITRD 0x54410005 -+ -+/* describes where the compressed ramdisk image lives (physical address) */ -+#define ATAG_INITRD2 0x54420005 -+ -+struct tag_initrd { -+ u32 start; //M Tom va of start addr /* physical start address */ -+ u32 size; //M Tom unzipped size /* size of compressed ramdisk image in bytes */ -+}; -+ -+/* board serial number. "64 bits should be enough for everybody" */ -+#define ATAG_SERIAL 0x54410006 -+ -+struct tag_serialnr { -+ u32 low; -+ u32 high; -+}; -+ -+/* board revision */ -+#define ATAG_REVISION 0x54410007 -+ -+struct tag_revision { -+ u32 rev; -+}; -+ -+/* initial values for vesafb-type framebuffers. see struct screen_info -+ * in include/linux/tty.h -+ */ -+#define ATAG_VIDEOLFB 0x54410008 -+ -+struct tag_videolfb { -+ u16 lfb_width; -+ u16 lfb_height; -+ u16 lfb_depth; -+ u16 lfb_linelength; -+ u32 lfb_base; -+ u32 lfb_size; -+ u8 red_size; -+ u8 red_pos; -+ u8 green_size; -+ u8 green_pos; -+ u8 blue_size; -+ u8 blue_pos; -+ u8 rsvd_size; -+ u8 rsvd_pos; -+}; -+ -+/* command line: \0 terminated string */ -+#define ATAG_CMDLINE 0x54410009 -+ -+struct tag_cmdline { -+ char cmdline[COMMAND_LINE_SIZE];//M Tom -+}; -+ -+/* acorn RiscPC specific information */ -+/*-d Tom -+#define ATAG_ACORN 0x41000101 -+ -+struct tag_acorn { -+ u32 memc_control_reg; -+ u32 vram_pages; -+ u8 sounddefault; -+ u8 adfsdrives; -+}; -+*/ -+#define ATAG_CPE 0x41000101 -+struct tag_cpe { -+ u32 memc_control_reg; -+ u32 vram_pages; -+ u8 sounddefault; -+ u8 adfsdrives; -+}; -+ -+ -+/* footbridge memory clock, see arch/arm/mach-footbridge/arch.c */ -+#define ATAG_MEMCLK 0x41000402 -+ -+struct tag_memclk { -+ u32 fmemclk; -+}; -+ -+struct tag { -+ struct tag_header hdr; -+ union { -+ struct tag_core core; -+ struct tag_mem32 mem; -+ struct tag_videotext videotext; -+ struct tag_ramdisk ramdisk; -+ struct tag_initrd initrd; -+ struct tag_serialnr serialnr; -+ struct tag_revision revision; -+ struct tag_videolfb videolfb; -+ struct tag_cmdline cmdline; -+ -+ /* -+ * Andes specific -+ */ -+ struct tag_cpe cpe; -+ -+ /* -+ * DC21285 specific -+ */ -+ struct tag_memclk memclk; -+ } u; -+}; -+ -+struct tagtable { -+ u32 tag; -+ int (*parse)(const struct tag *); -+}; -+ -+#define tag_member_present(tag,member) \ -+ ((unsigned long)(&((struct tag *)0L)->member + 1) \ -+ <= (tag)->hdr.size * 4) -+ -+#define tag_next(t) ((struct tag *)((u32 *)(t) + (t)->hdr.size)) -+#define tag_size(type) ((sizeof(struct tag_header) + sizeof(struct type)) >> 2) -+ -+#define for_each_tag(t,base) \ -+ for (t = base; t->hdr.size; t = tag_next(t)) -+ -+#ifdef __KERNEL__ -+ -+#define __tag __used __attribute__((__section__(".taglist"))) -+#define __tagtable(tag, fn) \ -+static struct tagtable __tagtable_##fn __tag = { tag, fn } -+ -+/* -+ * Memory map description -+ */ -+#ifdef CONFIG_ARCH_LH7A40X -+# define NR_BANKS 16 -+#else -+# define NR_BANKS 8 -+#endif -+ -+struct meminfo { -+ int nr_banks; -+ struct { -+ unsigned long start; -+ unsigned long size; -+ int node; -+ } bank[NR_BANKS]; -+}; -+ -+/* -+ * Early command line parameters. -+ */ -+struct early_params { -+ const char *arg; -+ void (*fn)(char **p); -+}; -+ -+#define __early_param(name,fn) \ -+static struct early_params __early_##fn __used \ -+__attribute__((__section__("__early_param"))) = { name, fn } -+ -+#endif -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/shmbuf.h linux-3.4.113/arch/nds32/include/asm/shmbuf.h ---- linux-3.4.113.orig/arch/nds32/include/asm/shmbuf.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/shmbuf.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,47 @@ -+/* -+ * linux/arch/nds32/include/asm/shmbuf.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SHMBUF_H -+#define _ASMNDS32_SHMBUF_H -+ -+/* -+ * The shmid64_ds structure for arm architecture. -+ * Note extra padding because this structure is passed back and forth -+ * between kernel and user space. -+ * -+ * Pad space is left for: -+ * - 64-bit time_t to solve y2038 problem -+ * - 2 miscellaneous 32-bit values -+ */ -+ -+struct shmid64_ds { -+ struct ipc64_perm shm_perm; /* operation perms */ -+ size_t shm_segsz; /* size of segment (bytes) */ -+ __kernel_time_t shm_atime; /* last attach time */ -+ unsigned long __unused1; -+ __kernel_time_t shm_dtime; /* last detach time */ -+ unsigned long __unused2; -+ __kernel_time_t shm_ctime; /* last change time */ -+ unsigned long __unused3; -+ __kernel_pid_t shm_cpid; /* pid of creator */ -+ __kernel_pid_t shm_lpid; /* pid of last operator */ -+ unsigned long shm_nattch; /* no. of current attaches */ -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+ -+struct shminfo64 { -+ unsigned long shmmax; -+ unsigned long shmmin; -+ unsigned long shmmni; -+ unsigned long shmseg; -+ unsigned long shmall; -+ unsigned long __unused1; -+ unsigned long __unused2; -+ unsigned long __unused3; -+ unsigned long __unused4; -+}; -+ -+#endif /* _ASMNDS32_SHMBUF_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/shmparam.h linux-3.4.113/arch/nds32/include/asm/shmparam.h ---- linux-3.4.113.orig/arch/nds32/include/asm/shmparam.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/shmparam.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,27 @@ -+/* -+ * linux/arch/nds32/include/asm/shmparam.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SHMPARAM_H -+#define _ASMNDS32_SHMPARAM_H -+ -+/* -+ * This should be the size of the virtually indexed cache/ways, -+ * whichever is greater since the cache aliases every size/ways -+ * bytes. -+ */ -+/* -+ * Reference ARM architecture, retain the previous code -+ * #define SHMLBA 0x4000 -+ * #define REALSHMLBA (CACHE_SET( DCACHE) * CACHE_LINE_SIZE( DCACHE)) -+ */ -+#define SHMLBA (4 * PAGE_SIZE) /* attach addr a multiple of this */ -+#define REALSHMLBA SHMLBA -+ -+/* -+ * Enforce SHMLBA in shmat -+ */ -+#define __ARCH_FORCE_SHMLBA -+ -+#endif /* _ASMNDS32_SHMPARAM_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/sigcontext.h linux-3.4.113/arch/nds32/include/asm/sigcontext.h ---- linux-3.4.113.orig/arch/nds32/include/asm/sigcontext.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/sigcontext.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,81 @@ -+/* -+ * linux/arch/nds32/include/asm/sigcontext.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SIGCONTEXT_H -+#define _ASMNDS32_SIGCONTEXT_H -+ -+/* -+ * Signal context structure - contains all info to do with the state -+ * before the signal handler was invoked. Note: only add new entries -+ * to the end of the structure. -+ */ -+struct fpu_struct { -+ unsigned long fs_regs[32]; -+ unsigned long long fd_regs[16]; -+ unsigned long fpcsr; -+}; -+ -+struct audio_struct { -+ unsigned long auregs[32]; -+}; -+ -+struct zol_struct { -+ unsigned long nds32_lc; /* $LC */ -+ unsigned long nds32_le; /* $LE */ -+ unsigned long nds32_lb; /* $LB */ -+}; -+ -+struct sigcontext { -+ unsigned long trap_no; -+ unsigned long error_code; -+ unsigned long oldmask; -+ unsigned long nds32_r0; -+ unsigned long nds32_r1; -+ unsigned long nds32_r2; -+ unsigned long nds32_r3; -+ unsigned long nds32_r4; -+ unsigned long nds32_r5; -+ unsigned long nds32_r6; -+ unsigned long nds32_r7; -+ unsigned long nds32_r8; -+ unsigned long nds32_r9; -+ unsigned long nds32_r10; -+ unsigned long nds32_r11; -+ unsigned long nds32_r12; -+ unsigned long nds32_r13; -+ unsigned long nds32_r14; -+ unsigned long nds32_r15; -+ unsigned long nds32_r16; -+ unsigned long nds32_r17; -+ unsigned long nds32_r18; -+ unsigned long nds32_r19; -+ unsigned long nds32_r20; -+ unsigned long nds32_r21; -+ unsigned long nds32_r22; -+ unsigned long nds32_r23; -+ unsigned long nds32_r24; -+ unsigned long nds32_r25; -+ unsigned long nds32_fp; /* $r28 */ -+ unsigned long nds32_gp; /* $r29 */ -+ unsigned long nds32_lr; /* $r30 */ -+ unsigned long nds32_sp; /* $r31 */ -+ unsigned long nds32_ipc; -+ unsigned long fault_address; -+#if defined(CONFIG_FPU) -+ unsigned long used_math_flag; -+ /* FPU Registers */ -+ struct fpu_struct fpu; -+#endif -+ /* Audio Registers */ -+#if defined(CONFIG_AUDIO) -+ unsigned long used_audio_flag; -+ struct audio_struct audio; -+#endif -+#if defined(CONFIG_HWZOL) -+ struct zol_struct zol; -+#endif -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/siginfo.h linux-3.4.113/arch/nds32/include/asm/siginfo.h ---- linux-3.4.113.orig/arch/nds32/include/asm/siginfo.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/siginfo.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/siginfo.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SIGINFO_H -+#define _ASMNDS32_SIGINFO_H -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/signal.h linux-3.4.113/arch/nds32/include/asm/signal.h ---- linux-3.4.113.orig/arch/nds32/include/asm/signal.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/signal.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,173 @@ -+/* -+ * linux/arch/nds32/include/asm/signal.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SIGNAL_H -+#define _ASMNDS32_SIGNAL_H -+ -+#include -+ -+/* Avoid too many header ordering problems. */ -+struct siginfo; -+ -+#ifdef __KERNEL__ -+/* Most things should be clean enough to redefine this at will, if care -+ is taken to make libc match. */ -+ -+#define _NSIG 64 -+#define _NSIG_BPW 32 -+#define _NSIG_WORDS (_NSIG / _NSIG_BPW) -+ -+typedef unsigned long old_sigset_t; /* at least 32 bits */ -+ -+typedef struct { -+ unsigned long sig[_NSIG_WORDS]; -+} sigset_t; -+ -+#else -+/* Here we must cater to libcs that poke about in kernel headers. */ -+ -+#define NSIG 32 -+typedef unsigned long sigset_t; -+ -+#endif /* __KERNEL__ */ -+ -+#define SIGHUP 1 -+#define SIGINT 2 -+#define SIGQUIT 3 -+#define SIGILL 4 -+#define SIGTRAP 5 -+#define SIGABRT 6 -+#define SIGIOT 6 -+#define SIGBUS 7 -+#define SIGFPE 8 -+#define SIGKILL 9 -+#define SIGUSR1 10 -+#define SIGSEGV 11 -+#define SIGUSR2 12 -+#define SIGPIPE 13 -+#define SIGALRM 14 -+#define SIGTERM 15 -+#define SIGSTKFLT 16 -+#define SIGCHLD 17 -+#define SIGCONT 18 -+#define SIGSTOP 19 -+#define SIGTSTP 20 -+#define SIGTTIN 21 -+#define SIGTTOU 22 -+#define SIGURG 23 -+#define SIGXCPU 24 -+#define SIGXFSZ 25 -+#define SIGVTALRM 26 -+#define SIGPROF 27 -+#define SIGWINCH 28 -+#define SIGIO 29 -+#define SIGPOLL SIGIO -+/* -+#define SIGLOST 29 -+*/ -+#define SIGPWR 30 -+#define SIGSYS 31 -+#define SIGUNUSED 31 -+ -+/* These should not be considered constants from userland. */ -+#define SIGRTMIN 32 -+#define SIGRTMAX _NSIG -+ -+#define SIGSWI 32 -+ -+/* -+ * SA_FLAGS values: -+ * -+ * SA_NOCLDSTOP flag to turn off SIGCHLD when children stop. -+ * SA_NOCLDWAIT flag on SIGCHLD to inhibit zombies. -+ * SA_SIGINFO deliver the signal with SIGINFO structs -+ * SA_THIRTYTWO delivers the signal in 32-bit mode, even if the task -+ * is running in 26-bit. -+ * SA_ONSTACK allows alternate signal stacks (see sigaltstack(2)). -+ * SA_RESTART flag to get restarting signals (which were the default long ago) -+ * SA_NODEFER prevents the current signal from being masked in the handler. -+ * SA_RESETHAND clears the handler when the signal is delivered. -+ * -+ * SA_ONESHOT and SA_NOMASK are the historical Linux names for the Single -+ * Unix names RESETHAND and NODEFER respectively. -+ */ -+#define SA_NOCLDSTOP 0x00000001 -+#define SA_NOCLDWAIT 0x00000002 -+#define SA_SIGINFO 0x00000004 -+#define SA_THIRTYTWO 0x02000000 -+#define SA_RESTORER 0x04000000 -+#define SA_ONSTACK 0x08000000 -+#define SA_RESTART 0x10000000 -+#define SA_NODEFER 0x40000000 -+#define SA_RESETHAND 0x80000000 -+ -+#define SA_NOMASK SA_NODEFER -+#define SA_ONESHOT SA_RESETHAND -+ -+ -+/* -+ * sigaltstack controls -+ */ -+#define SS_ONSTACK 1 -+#define SS_DISABLE 2 -+ -+#define MINSIGSTKSZ 2048 -+#define SIGSTKSZ 8192 -+ -+#ifdef __KERNEL__ -+#define SA_IRQNOMASK 0x08000000 -+#endif -+ -+#include -+ -+#ifdef __KERNEL__ -+struct old_sigaction { -+ __sighandler_t sa_handler; -+ old_sigset_t sa_mask; -+ unsigned long sa_flags; -+ __sigrestore_t sa_restorer; -+}; -+ -+struct sigaction { -+ __sighandler_t sa_handler; -+ unsigned long sa_flags; -+ __sigrestore_t sa_restorer; -+ sigset_t sa_mask; /* mask last for extensibility */ -+}; -+ -+struct k_sigaction { -+ struct sigaction sa; -+}; -+ -+#else -+/* Here we must cater to libcs that poke about in kernel headers. */ -+ -+struct sigaction { -+ union { -+ __sighandler_t _sa_handler; -+ void (*_sa_sigaction)(int, struct siginfo *, void *); -+ } _u; -+ sigset_t sa_mask; -+ unsigned long sa_flags; -+ void (*sa_restorer)(void); -+}; -+ -+#define sa_handler _u._sa_handler -+#define sa_sigaction _u._sa_sigaction -+ -+#endif /* __KERNEL__ */ -+ -+typedef struct sigaltstack { -+ void __user *ss_sp; -+ int ss_flags; -+ size_t ss_size; -+} stack_t; -+ -+#ifdef __KERNEL__ -+#include -+#define ptrace_signal_deliver(regs, cookie) do { } while (0) -+#endif -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/sizes.h linux-3.4.113/arch/nds32/include/asm/sizes.h ---- linux-3.4.113.orig/arch/nds32/include/asm/sizes.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/sizes.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,53 @@ -+/* -+ * 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 -+ */ -+/* DO NOT EDIT!! - this file automatically generated -+ * from .s file by awk -f s2h.awk -+ */ -+/* Size definitions -+ * Copyright (C) ARM Limited 1998. All rights reserved. -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __sizes_h -+#define __sizes_h 1 -+ -+/* handy sizes */ -+#define SZ_1K 0x00000400 -+#define SZ_4K 0x00001000 -+#define SZ_8K 0x00002000 -+#define SZ_16K 0x00004000 -+#define SZ_64K 0x00010000 -+#define SZ_128K 0x00020000 -+#define SZ_256K 0x00040000 -+#define SZ_512K 0x00080000 -+ -+#define SZ_1M 0x00100000 -+#define SZ_2M 0x00200000 -+#define SZ_4M 0x00400000 -+#define SZ_8M 0x00800000 -+#define SZ_16M 0x01000000 -+#define SZ_32M 0x02000000 -+#define SZ_64M 0x04000000 -+#define SZ_128M 0x08000000 -+#define SZ_256M 0x10000000 -+#define SZ_512M 0x20000000 -+ -+#define SZ_1G 0x40000000 -+#define SZ_2G 0x80000000 -+ -+#endif -+ -+/* END */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/smp.h linux-3.4.113/arch/nds32/include/asm/smp.h ---- linux-3.4.113.orig/arch/nds32/include/asm/smp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/smp.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,42 @@ -+/* -+ * linux/arch/nds32/include/asm/smp.h -+ * -+ * Copyright (C) 2004-2005 ARM Ltd. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_NDS32_SMP_H -+#define __ASM_NDS32_SMP_H -+ -+#include -+#include -+#include -+ -+#ifndef CONFIG_SMP -+# error " included in non-SMP build" -+#endif -+ -+/* -+ * at the moment, there's not a big penalty for changing CPUs -+ * (the >big< penalty is running SMP in the first place) -+ */ -+#define PROC_CHANGE_PENALTY 15 -+ -+struct seq_file; -+ -+/* -+ * Move global data into per-processor storage. -+ */ -+extern void smp_store_cpu_info(unsigned int cpuid); -+ -+#define raw_smp_processor_id() (unsigned int)(GET_CORE_ID()&CORE_ID_mskCOREID) -+ -+extern void smp_init_cpus(void); -+extern void smp_send_timer(void); -+extern void arch_send_call_function_single_ipi(int cpu); -+extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); -+ -+#endif /* ifndef __ASM_NDS32_SMP_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/socket.h linux-3.4.113/arch/nds32/include/asm/socket.h ---- linux-3.4.113.orig/arch/nds32/include/asm/socket.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/socket.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/socket.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SOCKET_H -+#define _ASMNDS32_SOCKET_H -+ -+#include -+ -+#endif /* _ASMNDS32_SOCKET_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/sockios.h linux-3.4.113/arch/nds32/include/asm/sockios.h ---- linux-3.4.113.orig/arch/nds32/include/asm/sockios.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/sockios.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,18 @@ -+/* -+ * linux/arch/nds32/include/asm/sockios.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ARCH_NDS32_SOCKIOS_H -+#define __ARCH_NDS32_SOCKIOS_H -+ -+/* Socket-level I/O control calls. */ -+#define FIOSETOWN 0x8901 -+#define SIOCSPGRP 0x8902 -+#define FIOGETOWN 0x8903 -+#define SIOCGPGRP 0x8904 -+#define SIOCATMARK 0x8905 -+#define SIOCGSTAMP 0x8906 /* Get stamp */ -+#define SIOCGSTAMPNS 0x8907 /* Get stamp (timespec) */ -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/spec-ag101.h linux-3.4.113/arch/nds32/include/asm/spec-ag101.h ---- linux-3.4.113.orig/arch/nds32/include/asm/spec-ag101.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/spec-ag101.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,237 @@ -+#ifndef __NDS32_AG101_SPECIFICATION_H__ -+#define __NDS32_AG101_SPECIFICATION_H__ -+ -+#define UART0_PA_BASE 0x99600000 -+#define UART0_VA_BASE 0xF9960000 -+#define UART0_IRQ 7 -+#define UART1_PA_BASE 0x98300000 -+#define UART1_VA_BASE 0xF9830000 -+#define UART1_IRQ 11 -+#define CFC_FTCFC010_0_PA_BASE 0x98D00000 -+#define CFC_FTCFC010_0_VA_BASE 0xF98D0000 -+#define SDC_FTSDC010_0_PA_BASE 0x98e00000 -+#define SDC_FTSDC010_0_VA_BASE 0xF98e0000 -+#define SDMC_FTSDMC021_PA_BASE 0x90300000 -+#define SDMC_FTSDMC021_VA_BASE 0xF9030000 -+#define PCIC_FTPCI100_0_PA_BASE 0x90C00000 -+#define PCIC_FTPCI100_0_VA_BASE 0xF90C0000 -+#define PCIC_FTPCI100_0_VA_LIMIT 0xF90CFFFF -+#define PCIIO_PA_BASE 0x90C01000 -+#define PCIIO_VA_BASE 0xFE901000 -+#define PCIIO_0_PA_BASE 0x90C01000 -+#define PCIIO_0_VA_BASE 0xFE901000 -+#define PCIIO_VA_LIMIT 0xFE9FFFFF -+#define AHB_ATFAHBC020S_0_PA_BASE 0x90100000 -+#define AHB_ATFAHBC020S_0_VA_BASE 0xF9010000 -+ -+/* DMAC */ -+#define DMAC_FTDMAC020_PA_COUNT 1 -+#define DMAC_FTDMAC020_PA_BASE 0x90400000 -+#define DMAC_FTDMAC020_PA_LIMIT 0x90400FFF -+#define DMAC_FTDMAC020_PA_SIZE 0x00001000 -+#define DMAC_FTDMAC020_0_PA_BASE 0x90400000 -+#define DMAC_FTDMAC020_0_PA_LIMIT 0x90400FFF -+#define DMAC_FTDMAC020_0_PA_SIZE 0x00001000 -+#define DMAC_FTDMAC020_VA_COUNT 1 -+#define DMAC_FTDMAC020_VA_BASE 0xF9040000 -+#define DMAC_FTDMAC020_VA_LIMIT 0xF9040FFF -+#define DMAC_FTDMAC020_VA_SIZE 0x00001000 -+#define DMAC_FTDMAC020_0_VA_BASE 0xF9040000 -+#define DMAC_FTDMAC020_0_VA_LIMIT 0xF9040FFF -+#define DMAC_FTDMAC020_0_VA_SIZE 0x00001000 -+ -+/* TIMER */ -+#define TIMER_FTTMR010_PA_COUNT 1 -+#define TIMER_FTTMR010_PA_BASE 0x98400000 -+#define TIMER_FTTMR010_PA_LIMIT 0x98400FFF -+#define TIMER_FTTMR010_PA_SIZE 0x00001000 -+#define TIMER_FTTMR010_0_PA_BASE 0x98400000 -+#define TIMER_FTTMR010_0_PA_LIMIT 0x98400FFF -+#define TIMER_FTTMR010_0_PA_SIZE 0x00001000 -+#define TIMER_FTTMR010_VA_COUNT 1 -+#define TIMER_FTTMR010_VA_BASE 0xF9840000 -+#define TIMER_FTTMR010_VA_LIMIT 0xF9840FFF -+#define TIMER_FTTMR010_VA_SIZE 0x00001000 -+#define TIMER_FTTMR010_0_VA_BASE 0xF9840000 -+#define TIMER_FTTMR010_0_VA_LIMIT 0xF9840FFF -+#define TIMER_FTTMR010_0_VA_SIZE 0x00001000 -+ -+/* RTC */ -+#define RTC_FTRTC010_PA_COUNT 1 -+#define RTC_FTRTC010_PA_BASE 0x98600000 -+#define RTC_FTRTC010_PA_LIMIT 0x98600FFF -+#define RTC_FTRTC010_PA_SIZE 0x00001000 -+#define RTC_FTRTC010_0_PA_BASE 0x98600000 -+#define RTC_FTRTC010_0_PA_LIMIT 0x98600FFF -+#define RTC_FTRTC010_0_PA_SIZE 0x00001000 -+#define RTC_FTRTC010_VA_COUNT 1 -+#define RTC_FTRTC010_VA_BASE 0xF9860000 -+#define RTC_FTRTC010_VA_LIMIT 0xF9860FFF -+#define RTC_FTRTC010_VA_SIZE 0x00001000 -+#define RTC_FTRTC010_0_VA_BASE 0xF9860000 -+#define RTC_FTRTC010_0_VA_LIMIT 0xF9860FFF -+#define RTC_FTRTC010_0_VA_SIZE 0x00001000 -+ -+/* WDT */ -+#define WDT_FTWDT010_PA_COUNT 1 -+#define WDT_FTWDT010_PA_BASE 0x98500000 -+#define WDT_FTWDT010_PA_LIMIT 0x98500FFF -+#define WDT_FTWDT010_PA_SIZE 0x00001000 -+#define WDT_FTWDT010_0_PA_BASE 0x98500000 -+#define WDT_FTWDT010_0_PA_LIMIT 0x98500FFF -+#define WDT_FTWDT010_0_PA_SIZE 0x00001000 -+#define WDT_FTWDT010_VA_COUNT 1 -+#define WDT_FTWDT010_VA_BASE 0xF9850000 -+#define WDT_FTWDT010_VA_LIMIT 0xF9850FFF -+#define WDT_FTWDT010_VA_SIZE 0x00001000 -+#define WDT_FTWDT010_0_VA_BASE 0xF9850000 -+#define WDT_FTWDT010_0_VA_LIMIT 0xF9850FFF -+#define WDT_FTWDT010_0_VA_SIZE 0x00001000 -+ -+/* GPIO */ -+#define GPIO_FTGPIO010_PA_COUNT 1 -+#define GPIO_FTGPIO010_PA_BASE 0x98700000 -+#define GPIO_FTGPIO010_PA_LIMIT 0x98700FFF -+#define GPIO_FTGPIO010_PA_SIZE 0x00001000 -+#define GPIO_FTGPIO010_0_PA_BASE 0x98700000 -+#define GPIO_FTGPIO010_0_PA_LIMIT 0x98700FFF -+#define GPIO_FTGPIO010_0_PA_SIZE 0x00001000 -+#define GPIO_FTGPIO010_VA_COUNT 1 -+#define GPIO_FTGPIO010_VA_BASE 0xF9870000 -+#define GPIO_FTGPIO010_VA_LIMIT 0xF9870FFF -+#define GPIO_FTGPIO010_VA_SIZE 0x00001000 -+#define GPIO_FTGPIO010_0_VA_BASE 0xF9870000 -+#define GPIO_FTGPIO010_0_VA_LIMIT 0xF9870FFF -+#define GPIO_FTGPIO010_0_VA_SIZE 0x00001000 -+ -+ -+/* USB OTG */ -+#define USB_FOTG2XX_0_PA_COUNT 1 -+#define USB_FOTG2XX_0_PA_BASE 0x90B00000 -+#define USB_FOTG2XX_0_PA_LIMIT 0x90B00FFF -+#define USB_FOTG2XX_0_PA_SIZE 0x00001000 -+#define USB_FOTG2XX_0_VA_BASE 0xF90B0000 -+#define USB_FOTG2XX_0_VA_LIMIT 0xF90B0FFF -+#define USB_FOTG2XX_0_VA_SIZE 0x00001000 -+#define USB_FOTG2XX_0_IRQ 26 -+#define USB_FOTG2XX_PA_COUNT 1 -+#define USB_FOTG2XX_PA_BASE 0x90B00000 -+#define USB_FOTG2XX_PA_LIMIT 0x90B00FFF -+#define USB_FOTG2XX_PA_SIZE 0x00001000 -+#define USB_FOTG2XX_VA_BASE 0xF90B0000 -+#define USB_FOTG2XX_VA_LIMIT 0xF90B0FFF -+#define USB_FOTG2XX_VA_SIZE 0x00001000 -+#define USB_FOTG2XX_IRQ 26 -+#define USB_FOTG2XX_IRQ_COUNT 1 -+ -+/* SSP */ -+#define SSP_FTSSP010_PA_COUNT 1 -+#define SSP_FTSSP010_PA_BASE 0x99400000 -+#define SSP_FTSSP010_PA_LIMIT 0x99400FFF -+#define SSP_FTSSP010_PA_SIZE 0x00001000 -+#define SSP_FTSSP010_0_PA_BASE 0x99400000 -+#define SSP_FTSSP010_0_PA_LIMIT 0x99400FFF -+#define SSP_FTSSP010_0_PA_SIZE 0x00001000 -+#define SSP_FTSSP010_VA_COUNT 1 -+#define SSP_FTSSP010_VA_BASE 0xF9940000 -+#define SSP_FTSSP010_VA_LIMIT 0xF9940FFF -+#define SSP_FTSSP010_VA_SIZE 0x00001000 -+#define SSP_FTSSP010_0_VA_BASE 0xF9940000 -+#define SSP_FTSSP010_0_VA_LIMIT 0xF9940FFF -+#define SSP_FTSSP010_0_VA_SIZE 0x00001000 -+ -+/* APBBRG */ -+#define APBBRG_FTAPBBRG020S_PA_COUNT 1 -+#define APBBRG_FTAPBBRG020S_PA_BASE 0x90500000 -+#define APBBRG_FTAPBBRG020S_PA_LIMIT 0x90500FFF -+#define APBBRG_FTAPBBRG020S_PA_SIZE 0x00001000 -+#define APBBRG_FTAPBBRG020S_0_PA_BASE 0x90500000 -+#define APBBRG_FTAPBBRG020S_0_PA_LIMIT 0x90500FFF -+#define APBBRG_FTAPBBRG020S_0_PA_SIZE 0x00001000 -+#define APBBRG_FTAPBBRG020S_1_PA_BASE 0x90E00000 -+#define APBBRG_FTAPBBRG020S_1_PA_LIMIT 0x90E00FFF -+#define APBBRG_FTAPBBRG020S_1_PA_SIZE 0x00001000 -+#define APBBRG_FTAPBBRG020S_VA_COUNT 1 -+#define APBBRG_FTAPBBRG020S_VA_BASE 0xF9050000 -+#define APBBRG_FTAPBBRG020S_VA_LIMIT 0xF9050FFF -+#define APBBRG_FTAPBBRG020S_VA_SIZE 0x00001000 -+#define APBBRG_FTAPBBRG020S_0_VA_BASE 0xF9050000 -+#define APBBRG_FTAPBBRG020S_0_VA_LIMIT 0xF9050FFF -+#define APBBRG_FTAPBBRG020S_0_VA_SIZE 0x00001000 -+#define APBBRG_FTAPBBRG020S_1_VA_BASE 0xF90E0000 -+#define APBBRG_FTAPBBRG020S_1_VA_LIMIT 0xF90E0FFF -+#define APBBRG_FTAPBBRG020S_1_VA_SIZE 0x00001000 -+ -+/* I2C */ -+#define I2C_FTI2C010_PA_COUNT 1 -+#define I2C_FTI2C010_PA_BASE 0x98A00000 -+#define I2C_FTI2C010_PA_LIMIT 0x98A00FFF -+#define I2C_FTI2C010_PA_SIZE 0x00001000 -+#define I2C_FTI2C010_0_PA_BASE 0x98A00000 -+#define I2C_FTI2C010_0_PA_LIMIT 0x98A00FFF -+#define I2C_FTI2C010_0_PA_SIZE 0x00001000 -+#define I2C_FTI2C010_VA_COUNT 1 -+#define I2C_FTI2C010_VA_BASE 0xF98A0000 -+#define I2C_FTI2C010_VA_LIMIT 0xF98A0FFF -+#define I2C_FTI2C010_VA_SIZE 0x00001000 -+#define I2C_FTI2C010_0_VA_BASE 0xF98A0000 -+#define I2C_FTI2C010_0_VA_LIMIT 0xF98A0FFF -+#define I2C_FTI2C010_0_VA_SIZE 0x00001000 -+ -+/* L2CC */ -+#define L2CC_PA_BASE 0x90F00000 /* reserved */ -+#define L2CC_VA_BASE 0xF90F0000 /* FIXME */ -+ -+#define LED_PA_COUNT 1 -+#define LED_PA_BASE 0x902FF000 -+#define LED_PA_LIMIT 0x90200FFF -+#define LED_PA_SIZE 0x00001000 -+#define LED_0_PA_BASE 0x90200000 -+#define LED_0_PA_LIMIT 0x90200FFF -+#define LED_0_PA_SIZE 0x00001000 -+#define LED_VA_COUNT 1 -+#define LED_VA_BASE 0xF9020000 -+#define LED_VA_LIMIT 0xF9020000 -+#define LED_VA_SIZE 0x00001000 -+#define LED_0_VA_BASE 0xF9020000 -+#define LED_0_VA_LIMIT 0xF9020000 -+#define LED_0_VA_SIZE 0x00001000 -+ -+/* MAC */ -+#define MAC_FTMAC100_PA_COUNT 1 -+#define MAC_FTMAC100_PA_BASE 0x90900000 -+#define MAC_FTMAC100_PA_LIMIT 0x90900FFF -+#define MAC_FTMAC100_PA_SIZE 0x00001000 -+#define MAC_FTMAC100_0_PA_BASE 0x90900000 -+#define MAC_FTMAC100_0_PA_LIMIT 0x90900FFF -+#define MAC_FTMAC100_0_PA_SIZE 0x00001000 -+#define MAC_FTMAC100_1_PA_BASE 0x92000000 -+#define MAC_FTMAC100_1_PA_LIMIT 0x92000FFF -+#define MAC_FTMAC100_1_PA_SIZE 0x00001000 -+#define MAC_FTMAC100_VA_COUNT 1 -+#define MAC_FTMAC100_VA_BASE 0xF9090000 -+#define MAC_FTMAC100_VA_LIMIT 0xF9090FFF -+#define MAC_FTMAC100_VA_SIZE 0x00001000 -+#define MAC_FTMAC100_0_VA_BASE 0xF9090000 -+#define MAC_FTMAC100_0_VA_LIMIT 0xF9090FFF -+#define MAC_FTMAC100_0_VA_SIZE 0x00001000 -+#define MAC_FTMAC100_1_VA_BASE 0xF9200000 -+#define MAC_FTMAC100_1_VA_LIMIT 0xF9200FFF -+#define MAC_FTMAC100_1_VA_SIZE 0x00001000 -+ -+/* LCD */ -+#define LCD_FTLCDC100_PA_COUNT 1 -+#define LCD_FTLCDC100_PA_BASE 0x90600000 -+#define LCD_FTLCDC100_PA_LIMIT 0x90600FFF -+#define LCD_FTLCDC100_PA_SIZE 0x00001000 -+#define LCD_FTLCDC100_0_PA_BASE 0x90600000 -+#define LCD_FTLCDC100_0_PA_LIMIT 0x90600FFF -+#define LCD_FTLCDC100_0_PA_SIZE 0x00001000 -+#define LCD_FTLCDC100_VA_COUNT 1 -+#define LCD_FTLCDC100_VA_BASE 0xF9060000 -+#define LCD_FTLCDC100_VA_LIMIT 0xF9060FFF -+#define LCD_FTLCDC100_VA_SIZE 0x00001000 -+#define LCD_FTLCDC100_0_VA_BASE 0xF9060000 -+#define LCD_FTLCDC100_0_VA_LIMIT 0xF9060FFF -+#define LCD_FTLCDC100_0_VA_SIZE 0x00001000 -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/spec-ag102.h linux-3.4.113/arch/nds32/include/asm/spec-ag102.h ---- linux-3.4.113.orig/arch/nds32/include/asm/spec-ag102.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/spec-ag102.h 2016-12-01 20:59:24.344612443 +0100 -@@ -0,0 +1,167 @@ -+#ifndef __NDS32_AG102_SPECIFICATION_H__ -+#define __NDS32_AG102_SPECIFICATION_H__ -+ -+#define UART0_PA_BASE 0x94200000 -+#define UART0_VA_BASE 0xF9420000 -+#define UART0_IRQ 10 -+#define UART1_PA_BASE 0x94600000 -+#define UART1_VA_BASE 0xF9460000 -+#define UART1_IRQ 11 -+#define AMIC_PA_BASE 0x90F00000 -+#define AMIC_VA_BASE 0xF90F0000 -+#define GMAC_PA_BASE 0x90B00000 -+#define GMAC_VA_BASE 0xF90B0000 -+#define APBBR_PA_BASE 0x90D00000 -+#define APBBR_VA_BASE 0xF90D0000 -+#define GMAC_IRQ 25 -+#define TIMER_PA_BASE 0x94900000 -+#define TIMER_VA_BASE 0xF9490000 -+#define L2CC_PA_BASE 0x90900000 -+#define L2CC_VA_BASE 0xF9090000 -+#define CFC_FTCFC010_0_PA_BASE 0x94000000 -+#define CFC_FTCFC010_0_VA_BASE 0xF9400000 -+#define SDC_FTSDC010_0_PA_BASE 0x94400000 -+#define SDC_FTSDC010_0_VA_BASE 0xF9440000 -+#define PCU_PA_BASE 0x94800000 -+#define PCU_VA_BASE 0xF9480000 -+#define PCIC_FTPCI100_0_PA_BASE 0x90000000 -+#define PCIC_FTPCI100_0_VA_BASE 0xF9000000 -+#define PCIC_FTPCI100_0_VA_LIMIT 0xF9000FFF -+#define PCIIO_PA_BASE 0x90001000 -+#define PCIIO_VA_BASE 0xF8901000 -+#define PCIIO_0_PA_BASE 0x90001000 -+#define PCIIO_0_VA_BASE 0xF8901000 -+#define PCIIO_VA_LIMIT 0xF89FFFFF -+#define LPC_IO_PA_BASE 0x90100000 -+#define LPC_IO_VA_BASE 0xF9010000 -+#define LPC_REG_PA_BASE 0x90200000 -+#define LPC_REG_VA_BASE 0xF9020000 -+#define LPC_IRQ 29 -+#define GPU_PA_BASE 0x90A00000 -+#define GPU_VA_BASE 0xFEA00000 -+#define IDE_FTIDE020_VA_BASE 0xF9070000 -+#define IDE_FTIDE020_PA_BASE 0x90700000 -+#define IDE_FTIDE020_IRQ 1 -+#define USB_FOTG2XX_0_PA_BASE 0x90800000 -+#define USB_FOTG2XX_0_VA_BASE 0xF9080000 -+#define USB_FOTG2XX_0_IRQ 26 -+#define DDR2C_PA_BASE 0x90500000 -+#define DDR2C_VA_BASE 0xF9050000 -+#define GPIO_VA_BASE 0xF94C0000 -+#define GPIO_PA_BASE 0x94C00000 -+ -+#define PLATFORM_LPC_IRQ_BASE 180 -+#define PLATFORM_LPC_IRQ_TOTALCOUNT 22 -+ -+/* DMAC */ -+#define DMAC_FTDMAC020_PA_COUNT 1 -+#define DMAC_FTDMAC020_PA_BASE 0x90600000 -+#define DMAC_FTDMAC020_PA_LIMIT 0x90600FFF -+#define DMAC_FTDMAC020_PA_SIZE 0x00001000 -+#define DMAC_FTDMAC020_0_PA_BASE 0x90600000 -+#define DMAC_FTDMAC020_0_PA_LIMIT 0x90600FFF -+#define DMAC_FTDMAC020_0_PA_SIZE 0x00001000 -+#define DMAC_FTDMAC020_VA_COUNT 1 -+#define DMAC_FTDMAC020_VA_BASE 0xF9060000 -+#define DMAC_FTDMAC020_VA_LIMIT 0xF9060FFF -+#define DMAC_FTDMAC020_VA_SIZE 0x00001000 -+#define DMAC_FTDMAC020_0_VA_BASE 0xF9060000 -+#define DMAC_FTDMAC020_0_VA_LIMIT 0xF9060FFF -+#define DMAC_FTDMAC020_0_VA_SIZE 0x00001000 -+ -+/* TIMER */ -+#define TIMER_FTTMR010_PA_COUNT 1 -+#define TIMER_FTTMR010_PA_BASE 0x94900000 -+#define TIMER_FTTMR010_PA_LIMIT 0x94900FFF -+#define TIMER_FTTMR010_PA_SIZE 0x00001000 -+#define TIMER_FTTMR010_0_PA_BASE 0x94900000 -+#define TIMER_FTTMR010_0_PA_LIMIT 0x94900FFF -+#define TIMER_FTTMR010_0_PA_SIZE 0x00001000 -+#define TIMER_FTTMR010_VA_COUNT 1 -+#define TIMER_FTTMR010_VA_BASE 0xF9490000 -+#define TIMER_FTTMR010_VA_LIMIT 0xF9490FFF -+#define TIMER_FTTMR010_VA_SIZE 0x00001000 -+#define TIMER_FTTMR010_0_VA_BASE 0xF9490000 -+#define TIMER_FTTMR010_0_VA_LIMIT 0xF9490FFF -+#define TIMER_FTTMR010_0_VA_SIZE 0x00001000 -+ -+/* WDT */ -+#define WDT_FTWDT010_PA_COUNT 1 -+#define WDT_FTWDT010_PA_BASE 0x94A00000 -+#define WDT_FTWDT010_PA_LIMIT 0x94A00FFF -+#define WDT_FTWDT010_PA_SIZE 0x00001000 -+#define WDT_FTWDT010_0_PA_BASE 0x94A00000 -+#define WDT_FTWDT010_0_PA_LIMIT 0x94A00FFF -+#define WDT_FTWDT010_0_PA_SIZE 0x00001000 -+#define WDT_FTWDT010_VA_COUNT 1 -+#define WDT_FTWDT010_VA_BASE 0xF94A0000 -+#define WDT_FTWDT010_VA_LIMIT 0xF94A0FFF -+#define WDT_FTWDT010_VA_SIZE 0x00001000 -+#define WDT_FTWDT010_0_VA_BASE 0xF94A0000 -+#define WDT_FTWDT010_0_VA_LIMIT 0xF94A0FFF -+#define WDT_FTWDT010_0_VA_SIZE 0x00001000 -+ -+/* RTC */ -+#define RTC_FTRTC010_PA_COUNT 1 -+#define RTC_FTRTC010_PA_BASE 0x94B00000 -+#define RTC_FTRTC010_PA_LIMIT 0x94B00FFF -+#define RTC_FTRTC010_PA_SIZE 0x00001000 -+#define RTC_FTRTC010_0_PA_BASE 0x94B00000 -+#define RTC_FTRTC010_0_PA_LIMIT 0x94B00FFF -+#define RTC_FTRTC010_0_PA_SIZE 0x00001000 -+#define RTC_FTRTC010_VA_COUNT 1 -+#define RTC_FTRTC010_VA_BASE 0xF94B0000 -+#define RTC_FTRTC010_VA_LIMIT 0xF94B0FFF -+#define RTC_FTRTC010_VA_SIZE 0x00001000 -+#define RTC_FTRTC010_0_VA_BASE 0xF94B0000 -+#define RTC_FTRTC010_0_VA_LIMIT 0xF94B0FFF -+#define RTC_FTRTC010_0_VA_SIZE 0x00001000 -+ -+/* GPIO */ -+#define GPIO_FTGPIO010_PA_COUNT 1 -+#define GPIO_FTGPIO010_PA_BASE 0x94C00000 -+#define GPIO_FTGPIO010_PA_LIMIT 0x94C00FFF -+#define GPIO_FTGPIO010_PA_SIZE 0x00001000 -+#define GPIO_FTGPIO010_0_PA_BASE 0x94C00000 -+#define GPIO_FTGPIO010_0_PA_LIMIT 0x94C00FFF -+#define GPIO_FTGPIO010_0_PA_SIZE 0x00001000 -+#define GPIO_FTGPIO010_VA_COUNT 1 -+#define GPIO_FTGPIO010_VA_BASE 0xF94C0000 -+#define GPIO_FTGPIO010_VA_LIMIT 0xF94C0FFF -+#define GPIO_FTGPIO010_VA_SIZE 0x00001000 -+#define GPIO_FTGPIO010_0_VA_BASE 0xF94C0000 -+#define GPIO_FTGPIO010_0_VA_LIMIT 0xF94C0FFF -+#define GPIO_FTGPIO010_0_VA_SIZE 0x00001000 -+ -+/* SSP */ -+#define SSP_FTSSP010_PA_BASE 0x94500000 -+#define SSP_FTSSP010_0_PA_BASE 0x94500000 -+#define SSP_FTSSP010_VA_BASE 0xF9450000 -+#define SSP_FTSSP010_0_VA_BASE 0xF9450000 -+ -+/* SPI */ -+#define SPI_FTSSP010_PA_BASE 0x94100000 -+#define SPI_FTSSP010_0_PA_BASE 0x94100000 -+#define SPI_FTSSP010_VA_BASE 0xF9410000 -+#define SPI_FTSSP010_0_VA_BASE 0xF9410000 -+ -+/* AHB Controller */ -+#define AHB_ATFAHBC020S_0_PA_BASE 0x90C00000 -+#define AHB_ATFAHBC020S_0_VA_BASE 0xF90C0000 -+ -+#define I2C_FTI2C010_PA_COUNT 1 -+#define I2C_FTI2C010_PA_BASE 0x94E00000 -+#define I2C_FTI2C010_PA_LIMIT 0x94E00FFF -+#define I2C_FTI2C010_PA_SIZE 0x00001000 -+#define I2C_FTI2C010_0_PA_BASE 0x94E00000 -+#define I2C_FTI2C010_0_PA_LIMIT 0x94E00FFF -+#define I2C_FTI2C010_0_PA_SIZE 0x00001000 -+#define I2C_FTI2C010_VA_COUNT 1 -+#define I2C_FTI2C010_VA_BASE 0xF94E0000 -+#define I2C_FTI2C010_VA_LIMIT 0xF94E0FFF -+#define I2C_FTI2C010_VA_SIZE 0x00001000 -+#define I2C_FTI2C010_0_VA_BASE 0xF94E0000 -+#define I2C_FTI2C010_0_VA_LIMIT 0xF94E0FFF -+#define I2C_FTI2C010_0_VA_SIZE 0x00001000 -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/spec.h linux-3.4.113/arch/nds32/include/asm/spec.h ---- linux-3.4.113.orig/arch/nds32/include/asm/spec.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/spec.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,510 @@ -+/* -+ * linux/arch/nds32/include/asm/spec.h -+ * -+ * AG101 Platform Independent Specification -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/14/2005 Created. -+ * 09/15/2005 Completed. -+ */ -+ -+#ifndef __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ -+#define __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ -+ -+#include -+#ifdef CONFIG_PLAT_AG102 -+#include -+#else -+#include -+#endif -+ -+/* -+ * Platform dependent specification -+ */ -+#define PLATFORM_NAME "Andes AG101" -+ -+/* -+ * Component counts -+ */ -+ -+/* INTC */ -+#define INTC_COUNT 2 -+#define INTC_FTINTC010_COUNT 2 -+/* TIMER */ -+#define TIMER_COUNT 1 -+#define TIMER_FTTMR010_COUNT 1 -+/* SSP */ -+#define SSP_COUNT 1 -+#define SSP_FTSSP010_COUNT 1 -+/* PMU */ -+#define PMU_COUNT 1 -+#define PMU_FTPMU010_COUNT 1 -+/* MAC */ -+#define MAC_COUNT 1 -+#define MAC_FTMAC100_COUNT 1 -+ -+/* SDC */ -+#define SDC_COUNT 1 -+#define SDC_FTSDC010_COUNT 1 -+/* AHBDMA */ -+#define AHBDMA_COUNT 1 -+/* APBDMA */ -+#define APBDMA_COUNT 1 -+/* RTC */ -+#define RTC_COUNT 1 -+#define RTC_FTRTC010_COUNT 1 -+/* WDT */ -+#define WDT_COUNT 1 -+#define WDT_FTWDT010_COUNT 1 -+/* GPIO */ -+#define GPIO_COUNT 1 -+#define GPIO_FTGPIO010_COUNT 1 -+/* CFC */ -+#define CFC_COUNT 1 -+#define CFC_FTCFC010_COUNT 1 -+/* LCD */ -+#define LCD_COUNT 1 -+#define LCD_FTLCDC100_COUNT 1 -+/* I2C */ -+#define I2C_COUNT 1 -+#define I2C_FTI2C010_COUNT 1 -+/* USB */ -+#define USB_COUNT 3 -+#define USB_FOTG2XX_COUNT 1 -+#define USB_FUSBH200_COUNT 1 -+#define USB_FUSB220_COUNT 1 -+/* DMAC */ -+#define DMAC_COUNT 1 -+#define DMAC_FTDMAC020_COUNT 1 -+/* KMI */ -+#define KMI_COUNT 2 -+#define KMI_FTKBC010_COUNT 2 -+/* PCI */ -+#define PCI_COUNT 1 -+/* PCIMEM */ -+#define PCIMEM_COUNT 1 -+/* PCIIO */ -+#define PCIIO_COUNT 1 -+/* PCIC */ -+#define PCIC_COUNT 1 -+#define PCIC_FTPCI100_COUNT 1 -+ -+/* -+ * Hierarchial Component IDs -+ */ -+ -+#define PLATFORM_AHBDMA_DMAC_FTDMAC020_ID 0 -+#define PLATFORM_APBDMA_APBBRG_FTAPBBRG020S_ID 0 -+ -+/* -+ * Number of interrupts -+ */ -+ -+#define PLATFORM_IRQ_TOTALCOUNT 32 -+#define PLATFORM_AHBDMA_IRQ_TOTALCOUNT 8 -+#define PLATFORM_APBDMA_IRQ_TOTALCOUNT 4 -+ -+#define PLATFORM_IRQ_BASE 0 -+#define PLATFORM_AHBDMA_IRQ_BASE 64 -+#define PLATFORM_APBDMA_IRQ_BASE 72 -+#define PLATFORM_PCI_IRQ_BASE 176 -+#define PLATFORM_INTERRUPTS 202 -+ -+/* -+ * IRQ trigger level and trigger mode -+ */ -+ -+#define PLATFORM_IRQ_TRIGGER_MODE 0x000EC880 -+#define PLATFORM_IRQ_TRIGGER_LEVEL 0x10000000 -+#define PLATFORM_AHBDMA_IRQ_TRIGGER_MODE 0x00000000 -+#define PLATFORM_AHBDMA_IRQ_TRIGGER_LEVEL 0xFFFFFFFF -+#define PLATFORM_APBDMA_IRQ_TRIGGER_MODE 0x00000000 -+#define PLATFORM_APBDMA_IRQ_TRIGGER_LEVEL 0xFFFFFFFF -+ -+/* -+ * Interrupt numbers of Hierarchical Architecture -+ */ -+ -+/* AHBDMA */ -+#define PLATFORM_AHBDMA_IRQ 21 -+ -+/* APBDMA */ -+#define PLATFORM_APBDMA_IRQ 24 -+ -+/* PCI */ -+#ifdef CONFIG_XC5_PCI -+#define PLATFORM_PCI_IRQ 10 -+#else -+#define PLATFORM_PCI_IRQ 28 -+#endif -+ -+ -+/* -+ * Interrrupt numbers -+ */ -+ -+/* TIMER */ -+#define TIMER_FTTMR010_IRQ_COUNT 3 -+#define TIMER_FTTMR010_IRQ0 19 -+#define TIMER_FTTMR010_0_IRQ0 19 -+#define TIMER_FTTMR010_IRQ1 14 -+#define TIMER_FTTMR010_0_IRQ1 14 -+#define TIMER_FTTMR010_IRQ2 15 -+#define TIMER_FTTMR010_0_IRQ2 15 -+ -+/* SSP */ -+#define SSP_FTSSP010_IRQ_COUNT 1 -+#define SSP_FTSSP010_IRQ 6 -+#define SSP_FTSSP010_0_IRQ 6 -+ -+/* MAC */ -+#define MAC_FTMAC100_IRQ_COUNT 1 -+#define MAC_FTMAC100_IRQ 25 -+#define MAC_FTMAC100_0_IRQ 25 -+#define MAC_FTMAC100_1_IRQ 133 -+ -+/* SDC */ -+#define SDC_FTSDC010_IRQ_COUNT 1 -+#define SDC_FTSDC010_IRQ 5 -+#define SDC_FTSDC010_0_IRQ 5 -+ -+/* RTC */ -+#define RTC_FTRTC010_IRQ_COUNT 2 -+#define RTC_FTRTC010_IRQ0 17 -+#define RTC_FTRTC010_0_IRQ0 17 -+#define RTC_FTRTC010_IRQ1 18 -+#define RTC_FTRTC010_0_IRQ1 18 -+ -+/* WDT */ -+#define WDT_FTWDT010_IRQ_COUNT 1 -+#define WDT_FTWDT010_IRQ 16 -+#define WDT_FTWDT010_0_IRQ 16 -+ -+/* GPIO */ -+#define GPIO_FTGPIO010_IRQ_COUNT 1 -+#define GPIO_FTGPIO010_IRQ 13 -+#define GPIO_FTGPIO010_0_IRQ 13 -+ -+/* CFC */ -+#define CFC_FTCFC010_IRQ_COUNT 2 -+#define CFC_FTCFC010_IRQ0 0 -+#define CFC_FTCFC010_0_IRQ0 0 -+#define CFC_FTCFC010_IRQ1 1 -+#define CFC_FTCFC010_0_IRQ1 1 -+ -+/* LCD */ -+#define LCD_FTLCDC100_IRQ_COUNT 1 -+#define LCD_FTLCDC100_IRQ 20 -+#define LCD_FTLCDC100_0_IRQ 20 -+ -+/* I2C */ -+#define I2C_FTI2C010_IRQ_COUNT 1 -+#define I2C_FTI2C010_IRQ 3 -+#define I2C_FTI2C010_0_IRQ 3 -+ -+/* USB */ -+#define USB_FUSBH200_IRQ_COUNT 1 -+#define USB_FUSBH200_IRQ 29 -+#define USB_FUSBH200_0_IRQ 29 -+#define USB_FUSB220_IRQ_COUNT 1 -+#define USB_FUSB220_IRQ 26 -+#define USB_FUSB220_0_IRQ 26 -+ -+/* DMAC */ -+#define DMAC_FTDMAC020_IRQ_COUNT 8 -+#define DMAC_FTDMAC020_IRQ0 64 -+#define DMAC_FTDMAC020_0_IRQ0 64 -+#define DMAC_FTDMAC020_IRQ1 65 -+#define DMAC_FTDMAC020_0_IRQ1 65 -+#define DMAC_FTDMAC020_IRQ2 66 -+#define DMAC_FTDMAC020_0_IRQ2 66 -+#define DMAC_FTDMAC020_IRQ3 67 -+#define DMAC_FTDMAC020_0_IRQ3 67 -+#define DMAC_FTDMAC020_IRQ4 68 -+#define DMAC_FTDMAC020_0_IRQ4 68 -+#define DMAC_FTDMAC020_IRQ5 69 -+#define DMAC_FTDMAC020_0_IRQ5 69 -+#define DMAC_FTDMAC020_IRQ6 70 -+#define DMAC_FTDMAC020_0_IRQ6 70 -+#define DMAC_FTDMAC020_IRQ7 71 -+#define DMAC_FTDMAC020_0_IRQ7 71 -+ -+/* APBBRG */ -+#define APBBRG_FTAPBBRG020S_IRQ_COUNT 4 -+#define APBBRG_FTAPBBRG020S_IRQ0 72 -+#define APBBRG_FTAPBBRG020S_0_IRQ0 72 -+#define APBBRG_FTAPBBRG020S_IRQ1 73 -+#define APBBRG_FTAPBBRG020S_0_IRQ1 73 -+#define APBBRG_FTAPBBRG020S_IRQ2 74 -+#define APBBRG_FTAPBBRG020S_0_IRQ2 74 -+#define APBBRG_FTAPBBRG020S_IRQ3 75 -+#define APBBRG_FTAPBBRG020S_0_IRQ3 75 -+#define APBBRG_FTAPBBRG020S_1_IRQ0 172 -+#define APBBRG_FTAPBBRG020S_1_IRQ1 173 -+#define APBBRG_FTAPBBRG020S_1_IRQ2 174 -+#define APBBRG_FTAPBBRG020S_1_IRQ3 175 -+ -+/* KMI */ -+#define KMI_FTKBC010_IRQ_COUNT 1 -+#define KMI_FTKBC010_IRQ 30 -+#define KMI_FTKBC010_0_IRQ 30 -+#define KMI_FTKBC010_1_IRQ 31 -+ -+/* PCIC */ -+#define PCIC_FTPCI100_IRQ_COUNT 4 -+#define PCIC_FTPCI100_IRQ0 176 -+#define PCIC_FTPCI100_0_IRQ0 176 -+#define PCIC_FTPCI100_IRQ1 177 -+#define PCIC_FTPCI100_0_IRQ1 177 -+#define PCIC_FTPCI100_IRQ2 178 -+#define PCIC_FTPCI100_0_IRQ2 178 -+#define PCIC_FTPCI100_IRQ3 179 -+#define PCIC_FTPCI100_0_IRQ3 179 -+ -+/* -+ * Base addresses -+ */ -+ -+/* CPU */ -+#define CPU_MEM_PA_BASE CONFIG_MEMORY_START -+ -+ -+/* INTC */ -+#define INTC_FTINTC010_PA_COUNT 1 -+#define INTC_FTINTC010_PA_BASE 0x98800000 -+#define INTC_FTINTC010_PA_LIMIT 0x98800FFF -+#define INTC_FTINTC010_PA_SIZE 0x00001000 -+#define INTC_FTINTC010_0_PA_BASE 0x98800000 -+#define INTC_FTINTC010_0_PA_LIMIT 0x98800FFF -+#define INTC_FTINTC010_0_PA_SIZE 0x00001000 -+#define INTC_FTINTC010_1_PA_BASE 0xB0800000 -+#define INTC_FTINTC010_1_PA_LIMIT 0xB0800FFF -+#define INTC_FTINTC010_1_PA_SIZE 0x00001000 -+#define INTC_FTINTC010_VA_COUNT 1 -+#define INTC_FTINTC010_VA_BASE 0xF9880000 -+#define INTC_FTINTC010_VA_LIMIT 0xF9880FFF -+#define INTC_FTINTC010_VA_SIZE 0x00001000 -+#define INTC_FTINTC010_0_VA_BASE 0xF9880000 -+#define INTC_FTINTC010_0_VA_LIMIT 0xF9880FFF -+#define INTC_FTINTC010_0_VA_SIZE 0x00001000 -+#define INTC_FTINTC010_1_VA_BASE 0xFB080000 -+#define INTC_FTINTC010_1_VA_LIMIT 0xFB080FFF -+#define INTC_FTINTC010_1_VA_SIZE 0x00001000 -+ -+/* PMU */ -+#define PMU_FTPMU010_PA_COUNT 1 -+#define PMU_FTPMU010_PA_BASE 0x98100000 -+#define PMU_FTPMU010_PA_LIMIT 0x98100FFF -+#define PMU_FTPMU010_PA_SIZE 0x00001000 -+#define PMU_FTPMU010_0_PA_BASE 0x98100000 -+#define PMU_FTPMU010_0_PA_LIMIT 0x98100FFF -+#define PMU_FTPMU010_0_PA_SIZE 0x00001000 -+#define PMU_FTPMU010_VA_COUNT 1 -+#define PMU_FTPMU010_VA_BASE 0xF9810000 -+#define PMU_FTPMU010_VA_LIMIT 0xF9810FFF -+#define PMU_FTPMU010_VA_SIZE 0x00001000 -+#define PMU_FTPMU010_0_VA_BASE 0xF9810000 -+#define PMU_FTPMU010_0_VA_LIMIT 0xF9810FFF -+#define PMU_FTPMU010_0_VA_SIZE 0x00001000 -+ -+/* USB */ -+#define USB_FUSBH200_PA_COUNT 1 -+#define USB_FUSBH200_PA_BASE 0x92000000 -+#define USB_FUSBH200_PA_LIMIT 0x92000FFF -+#define USB_FUSBH200_PA_SIZE 0x00001000 -+#define USB_FUSBH200_0_PA_BASE 0x92000000 -+#define USB_FUSBH200_0_PA_LIMIT 0x92000FFF -+#define USB_FUSBH200_0_PA_SIZE 0x00001000 -+#define USB_FUSBH200_VA_COUNT 1 -+#define USB_FUSBH200_VA_BASE 0xF9200000 -+#define USB_FUSBH200_VA_LIMIT 0xF9200FFF -+#define USB_FUSBH200_VA_SIZE 0x00001000 -+#define USB_FUSBH200_0_VA_BASE 0xF9200000 -+#define USB_FUSBH200_0_VA_LIMIT 0xF9200FFF -+#define USB_FUSBH200_0_VA_SIZE 0x00001000 -+#define USB_FUSB220_PA_COUNT 1 -+#define USB_FUSB220_PA_BASE 0x90B00000 -+#define USB_FUSB220_PA_LIMIT 0x90B00FFF -+#define USB_FUSB220_PA_SIZE 0x00001000 -+#define USB_FUSB220_0_PA_BASE 0x90B00000 -+#define USB_FUSB220_0_PA_LIMIT 0x90B00FFF -+#define USB_FUSB220_0_PA_SIZE 0x00001000 -+#define USB_FUSB220_VA_COUNT 1 -+#define USB_FUSB220_VA_BASE 0xF90B0000 -+#define USB_FUSB220_VA_LIMIT 0xF90B0FFF -+#define USB_FUSB220_VA_SIZE 0x00001000 -+#define USB_FUSB220_0_VA_BASE 0xF90B0000 -+#define USB_FUSB220_0_VA_LIMIT 0xF90B0FFF -+#define USB_FUSB220_0_VA_SIZE 0x00001000 -+ -+/* KMI */ -+#define KMI_FTKBC010_PA_COUNT 1 -+#define KMI_FTKBC010_PA_BASE 0x97200000 -+#define KMI_FTKBC010_PA_LIMIT 0x97200FFF -+#define KMI_FTKBC010_PA_SIZE 0x00001000 -+#define KMI_FTKBC010_0_PA_BASE 0x97200000 -+#define KMI_FTKBC010_0_PA_LIMIT 0x97200FFF -+#define KMI_FTKBC010_0_PA_SIZE 0x00001000 -+#define KMI_FTKBC010_1_PA_BASE 0x97300000 -+#define KMI_FTKBC010_1_PA_LIMIT 0x97300FFF -+#define KMI_FTKBC010_1_PA_SIZE 0x00001000 -+#define KMI_FTKBC010_VA_COUNT 1 -+#define KMI_FTKBC010_VA_BASE 0xF9720000 -+#define KMI_FTKBC010_VA_LIMIT 0xF9720FFF -+#define KMI_FTKBC010_VA_SIZE 0x00001000 -+#define KMI_FTKBC010_0_VA_BASE 0xF9720000 -+#define KMI_FTKBC010_0_VA_LIMIT 0xF9720FFF -+#define KMI_FTKBC010_0_VA_SIZE 0x00001000 -+#define KMI_FTKBC010_1_VA_BASE 0xF9730000 -+#define KMI_FTKBC010_1_VA_LIMIT 0xF9730FFF -+#define KMI_FTKBC010_1_VA_SIZE 0x00001000 -+ -+/* PCIMEM */ -+#define PCIMEM_PA_COUNT 1 -+#define PCIMEM_PA_BASE 0xA0000000 -+#define PCIMEM_PA_LIMIT 0xAFFFFFFF -+#define PCIMEM_PA_SIZE 0x10000000 -+#define PCIMEM_0_PA_BASE 0xA0000000 -+#define PCIMEM_0_PA_LIMIT 0xAFFFFFFF -+#define PCIMEM_0_PA_SIZE 0x10000000 -+ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA_MODULE -+#define CONFIG_PLATFORM_AHBDMA -+#endif -+ -+#ifdef CONFIG_PLATFORM_APBDMA_MODULE -+#define CONFIG_PLATFORM_APBDMA -+#endif -+ -+#include /* Manual defined spec */ -+ -+/* -+ * Platform independent specification -+ */ -+ -+#define NR_IRQS PLATFORM_INTERRUPTS -+ -+#ifndef TIMER_CLK_IN -+#error Missing platform dependent symbol TIMER_CLK_IN in file. -+#endif -+ -+/* -+ * Macros for retrieving IP related information -+ */ -+#define IP_IDENTIFIER __glue(__glue(IPMODULE,_),__glue(IPNAME,_)) -+ -+#define IP_COUNT __glue(IP_IDENTIFIER,COUNT) -+ -+#define IP_IRQ_COUNT __glue(IP_IDENTIFIER,IRQ_COUNT) -+#define IP_IRQ(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ) -+#define IP_irq __glue(IP_IDENTIFIER,irq) -+ -+#define IP_PA_COUNT __glue(IP_IDENTIFIER,PA_COUNT) -+#define IP_PA_BASE(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE) -+#define IP_PA_LIMIT(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT) -+#define IP_PA_SIZE(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE) -+#define IP_pa_base __glue(IP_IDENTIFIER,pa_base) -+#define IP_pa_limit __glue(IP_IDENTIFIER,pa_limit) -+#define IP_pa_size __glue(IP_IDENTIFIER,pa_size) -+ -+#define IP_VA_COUNT __glue(IP_IDENTIFIER,VA_COUNT) -+#define IP_VA_BASE(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE) -+#define IP_VA_LIMIT(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT) -+#define IP_VA_SIZE(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE) -+#define IP_va_base __glue(IP_IDENTIFIER,va_base) -+#define IP_va_limit __glue(IP_IDENTIFIER,va_limit) -+#define IP_va_size __glue(IP_IDENTIFIER,va_size) -+ -+/* -+ * Facility macros -+ */ -+/* IRQ0~7 */ -+#define IP_IRQ0(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ0) -+#define IP_IRQ1(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ1) -+#define IP_IRQ2(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ2) -+#define IP_IRQ3(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ3) -+#define IP_IRQ4(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ4) -+#define IP_IRQ5(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ5) -+#define IP_IRQ6(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ6) -+#define IP_IRQ7(n) __glue(__glue(IP_IDENTIFIER,n),_IRQ7) -+ -+/* PA_BASE0~7 */ -+#define IP_PA_BASE0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE0) -+#define IP_PA_BASE1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE1) -+#define IP_PA_BASE2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE2) -+#define IP_PA_BASE3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE3) -+#define IP_PA_BASE4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE4) -+#define IP_PA_BASE5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE5) -+#define IP_PA_BASE6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE6) -+#define IP_PA_BASE7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_BASE7) -+ -+/* PA_LIMIT0~7 */ -+#define IP_PA_LIMIT0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT0) -+#define IP_PA_LIMIT1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT1) -+#define IP_PA_LIMIT2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT2) -+#define IP_PA_LIMIT3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT3) -+#define IP_PA_LIMIT4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT4) -+#define IP_PA_LIMIT5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT5) -+#define IP_PA_LIMIT6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT6) -+#define IP_PA_LIMIT7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_LIMIT7) -+ -+/* PA_SIZE0~7 */ -+#define IP_PA_SIZE0(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE0) -+#define IP_PA_SIZE1(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE1) -+#define IP_PA_SIZE2(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE2) -+#define IP_PA_SIZE3(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE3) -+#define IP_PA_SIZE4(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE4) -+#define IP_PA_SIZE5(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE5) -+#define IP_PA_SIZE6(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE6) -+#define IP_PA_SIZE7(n) __glue(__glue(IP_IDENTIFIER,n),_PA_SIZE7) -+ -+/* VA_BASE0~7 */ -+#define IP_VA_BASE0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE0) -+#define IP_VA_BASE1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE1) -+#define IP_VA_BASE2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE2) -+#define IP_VA_BASE3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE3) -+#define IP_VA_BASE4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE4) -+#define IP_VA_BASE5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE5) -+#define IP_VA_BASE6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE6) -+#define IP_VA_BASE7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_BASE7) -+ -+/* VA_LIMIT0~7 */ -+#define IP_VA_LIMIT0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT0) -+#define IP_VA_LIMIT1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT1) -+#define IP_VA_LIMIT2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT2) -+#define IP_VA_LIMIT3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT3) -+#define IP_VA_LIMIT4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT4) -+#define IP_VA_LIMIT5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT5) -+#define IP_VA_LIMIT6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT6) -+#define IP_VA_LIMIT7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_LIMIT7) -+ -+/* VA_SIZE0~7 */ -+#define IP_VA_SIZE0(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE0) -+#define IP_VA_SIZE1(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE1) -+#define IP_VA_SIZE2(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE2) -+#define IP_VA_SIZE3(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE3) -+#define IP_VA_SIZE4(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE4) -+#define IP_VA_SIZE5(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE5) -+#define IP_VA_SIZE6(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE6) -+#define IP_VA_SIZE7(n) __glue(__glue(IP_IDENTIFIER,n),_VA_SIZE7) -+ -+#endif /* __FARADAY_PLATFORM_INDEPENDENT_SPECIFICATION__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/spinlock.h linux-3.4.113/arch/nds32/include/asm/spinlock.h ---- linux-3.4.113.orig/arch/nds32/include/asm/spinlock.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/spinlock.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,183 @@ -+/* -+ * linux/arch/nds32/include/asm/spinlock.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_SPINLOCK_H -+#define __ASM_SPINLOCK_H -+ -+#include -+ -+#define arch_spin_is_locked(x) ((x)->lock != 0) -+ -+#define arch_spin_unlock_wait(lock) \ -+ do { while (arch_spin_is_locked(lock)) cpu_relax(); } while (0) -+ -+#define arch_spin_lock_flags(lock, flags) arch_spin_lock(lock) -+ -+static inline void arch_spin_lock(arch_spinlock_t *lock) -+{ -+ unsigned long tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tbnez\t%0, 1b\n" -+ "\tmovi\t%0, #0x1\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (&lock->lock) -+ : "memory"); -+} -+ -+static inline int arch_spin_trylock(arch_spinlock_t *lock) -+{ -+ unsigned long ret, tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%2+$r15]\n" -+ "\tmovi\t%1, #0x1\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ : "=&r" (ret), "=&r" (tmp) -+ : "r" (&lock->lock) -+ : "memory"); -+ -+ return ret == 0; -+} -+ -+static inline void arch_spin_unlock(arch_spinlock_t *lock) -+{ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "\tswi\t$r15, [%0]\n" -+ : -+ : "r" (&lock->lock) -+ : "memory"); -+} -+ -+static inline void arch_write_lock(arch_rwlock_t *rw) -+{ -+ unsigned long tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tbnez\t%0, 1b\n" -+ "\tsethi\t%0, 0x80000\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (&rw->lock) -+ : "memory"); -+} -+ -+static inline void arch_write_unlock(arch_rwlock_t *rw) -+{ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "\tswi\t$r15, [%0]\n" -+ : -+ : "r" (&rw->lock) -+ : "memory"); -+} -+ -+#define arch_write_can_lock(x) ((x)->lock == 0) -+static inline void arch_read_lock(arch_rwlock_t *rw) -+{ -+ int tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\tbltz\t%0, 1b\n" -+ "\taddi\t%0, %0, #1\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (&rw->lock) -+ : "memory"); -+} -+ -+static inline void arch_read_unlock(arch_rwlock_t *rw) -+{ -+ unsigned long tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "1:\n" -+ "\tllw\t%0, [%1+$r15]\n" -+ "\taddi\t%0, %0, #-1\n" -+ "\tscw\t%0, [%1+$r15]\n" -+ "\tbeqz\t%0, 1b\n" -+ : "=&r" (tmp) -+ : "r" (&rw->lock) -+ : "memory"); -+} -+ -+static inline int arch_read_trylock(arch_rwlock_t *rw) -+{ -+ unsigned long ret, tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "\tmovi\t%0, #0x0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\tbltz\t%1, 2f\n" -+ "\taddi\t%1, %1, #1\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ "\tmovi\t%0, #0x1\n" -+ "\tj\t3f\n" -+ "2:\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "3:\n" -+ : "=&r" (ret), "=&r" (tmp) -+ : "r" (&rw->lock) -+ : "memory"); -+ -+ return ret; -+} -+ -+static inline int arch_write_trylock(arch_rwlock_t *rw) -+{ -+ unsigned long ret, tmp; -+ -+ __asm__ __volatile__( -+ "xor\t$r15, $r15, $r15\n" -+ "\tmovi\t%0, #0x0\n" -+ "1:\n" -+ "\tllw\t%1, [%2+$r15]\n" -+ "\tbnez\t%1, 2f\n" -+ "\tsethi\t%1, 0x80000\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "\tbeqz\t%1, 1b\n" -+ "\tmovi\t%0, #0x1\n" -+ "\tj\t3f\n" -+ "2:\n" -+ "\tscw\t%1, [%2+$r15]\n" -+ "3:\n" -+ : "=&r" (ret), "=&r" (tmp) -+ : "r" (&rw->lock) -+ : "memory"); -+ -+ return ret; -+} -+ -+#define arch_read_lock_flags(lock, flags) arch_read_lock(lock) -+#define arch_write_lock_flags(lock, flags) arch_write_lock(lock) -+ -+#define arch_read_can_lock(x) ((x)->lock < 0x80000000) -+ -+#define arch_spin_relax(lock) cpu_relax() -+#define arch_read_relax(lock) cpu_relax() -+#define arch_write_relax(lock) cpu_relax() -+ -+#endif /* __ASM_SPINLOCK_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/spinlock_types.h linux-3.4.113/arch/nds32/include/asm/spinlock_types.h ---- linux-3.4.113.orig/arch/nds32/include/asm/spinlock_types.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/spinlock_types.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * linux/arch/nds32/include/asm/spinlock_types.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASM_SPINLOCK_TYPES_H -+#define _ASM_SPINLOCK_TYPES_H -+ -+#ifndef __LINUX_SPINLOCK_TYPES_H -+# error "please don't include this file directly" -+#endif -+ -+typedef struct { -+ volatile unsigned int lock; -+} arch_spinlock_t; -+ -+#define __ARCH_SPIN_LOCK_UNLOCKED { 0 } -+ -+typedef struct { -+ volatile unsigned int lock; -+} arch_rwlock_t; -+ -+#define __ARCH_RW_LOCK_UNLOCKED { 0 } -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/statfs.h linux-3.4.113/arch/nds32/include/asm/statfs.h ---- linux-3.4.113.orig/arch/nds32/include/asm/statfs.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/statfs.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/statfs.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_STATFS_H -+#define _ASMNDS32_STATFS_H -+ -+#include -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/stat.h linux-3.4.113/arch/nds32/include/asm/stat.h ---- linux-3.4.113.orig/arch/nds32/include/asm/stat.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/stat.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,101 @@ -+/* -+ * linux/arch/nds32/include/asm/stat.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_STAT_H -+#define _ASMNDS32_STAT_H -+ -+struct __old_kernel_stat { -+ unsigned short st_dev; -+ unsigned short st_ino; -+ unsigned short st_mode; -+ unsigned short st_nlink; -+ unsigned short st_uid; -+ unsigned short st_gid; -+ unsigned short st_rdev; -+ unsigned long st_size; -+ unsigned long st_atime; -+ unsigned long st_mtime; -+ unsigned long st_ctime; -+}; -+ -+#define STAT_HAVE_NSEC -+ -+struct stat { -+#if defined(__NDS32_EB__) -+ unsigned short st_dev; -+ unsigned short __pad1; -+#else -+ unsigned long st_dev; -+#endif -+ unsigned long st_ino; -+ unsigned short st_mode; -+ unsigned short st_nlink; -+ unsigned short st_uid; -+ unsigned short st_gid; -+#if defined(__NDS32_EB__) -+ unsigned short st_rdev; -+ unsigned short __pad2; -+#else -+ unsigned long st_rdev; -+#endif -+ unsigned long st_size; -+ unsigned long st_blksize; -+ unsigned long st_blocks; -+ unsigned long st_atime; -+ unsigned long st_atime_nsec; -+ unsigned long st_mtime; -+ unsigned long st_mtime_nsec; -+ unsigned long st_ctime; -+ unsigned long st_ctime_nsec; -+ unsigned long __unused4; -+ unsigned long __unused5; -+}; -+ -+/* This matches struct stat64 in glibc2.1, hence the absolutely -+ * insane amounts of padding around dev_t's. -+ * Note: The kernel zero's the padded region because glibc might read them -+ * in the hope that the kernel has stretched to using larger sizes. -+ */ -+ -+struct stat64 { -+ unsigned long long st_dev; -+ unsigned long __pad0; -+ -+#define STAT64_HAS_BROKEN_ST_INO 1 -+ unsigned long __st_ino; -+ unsigned int st_mode; -+ unsigned int st_nlink; -+ -+ unsigned long st_uid; -+ unsigned long st_gid; -+ -+ unsigned long long st_rdev; -+ unsigned int __pad3; -+ -+ unsigned long long st_size; -+ unsigned long st_blksize; -+ -+//#if defined(__NDS32EB__) -+// unsigned long __pad4; // Future possible st_blocks hi bits -+ unsigned long long st_blocks; // Number 512-byte blocks allocated. -+//#else // Must be little -+// unsigned long st_blocks; // Number 512-byte blocks allocated. -+// unsigned long __pad4; // Future possible st_blocks hi bits -+//#endif -+ -+ unsigned long st_atime; -+ unsigned long st_atime_nsec; -+ -+ unsigned long st_mtime; -+ unsigned long st_mtime_nsec; -+ -+ unsigned long st_ctime; -+ unsigned long st_ctime_nsec; -+ -+ unsigned long long st_ino; -+}; -+ -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/string.h linux-3.4.113/arch/nds32/include/asm/string.h ---- linux-3.4.113.orig/arch/nds32/include/asm/string.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/string.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,45 @@ -+/* -+ * linux/arch/nds32/include/asm/string.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_STRING_H -+#define __ASM_NDS32_STRING_H -+ -+/* -+ * We don't do inline string functions, since the -+ * optimised inline asm versions are not small. -+ */ -+ -+#define __HAVE_ARCH_STRRCHR -+extern char * strrchr(const char * s, int c); -+ -+#define __HAVE_ARCH_STRCHR -+extern char * strchr(const char * s, int c); -+ -+#define __HAVE_ARCH_MEMCPY -+extern void * memcpy(void *, const void *, __kernel_size_t); -+ -+#define __HAVE_ARCH_MEMMOVE -+extern void * memmove(void *, const void *, __kernel_size_t); -+ -+#define __HAVE_ARCH_MEMZERO -+#define __HAVE_ARCH_MEMSET -+extern void * memset(void *, int, __kernel_size_t); -+ -+extern void __memzero(void *ptr, __kernel_size_t n); -+ -+#define memset(p,v,n) \ -+ ({ \ -+ if ((n) != 0) { \ -+ if (__builtin_constant_p((v)) && (v) == 0) \ -+ __memzero((p),(n)); \ -+ else \ -+ memset((p),(v),(n)); \ -+ } \ -+ (p); \ -+ }) -+ -+#define memzero(p,n) ({ if ((n) != 0) __memzero((p),(n)); (p); }) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/suspend.h linux-3.4.113/arch/nds32/include/asm/suspend.h ---- linux-3.4.113.orig/arch/nds32/include/asm/suspend.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/suspend.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,9 @@ -+/* -+ * linux/arch/nds32/include/asm/suspend.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_SUSPEND_H -+#define _ASMNDS32_SUSPEND_H -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/swab.h linux-3.4.113/arch/nds32/include/asm/swab.h ---- linux-3.4.113.orig/arch/nds32/include/asm/swab.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/swab.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,34 @@ -+/* -+ * include/asm/byteorder.h -+ * Copyright (C) 2008 Andes Technology, Inc. -+ */ -+ -+#ifndef __NDS32_SWAB_H__ -+#define __NDS32_SWAB_H__ -+ -+#include -+#include -+ -+static __inline__ __attribute_const__ __u32 ___arch__swab32(__u32 x) -+{ -+ __asm__("wsbh %0, %0\n\t" /* word swap byte within halfword */ -+ "rotri %0, %0, #16\n" -+ : "=r" (x) : "0" (x)); -+ return x; -+} -+ -+static __inline__ __attribute_const__ __u16 ___arch__swab16(__u16 x) -+{ -+ __asm__("wsbh %0, %0\n" /* word swap byte within halfword */ -+ : "=r" (x) : "0" (x)); -+ return x; -+} -+#define __arch_swab32(x) ___arch__swab32(x) -+#define __arch_swab16(x) ___arch__swab16(x) -+ -+#if !defined(__STRICT_ANSI__) || defined(__KERNEL__) -+# define __BYTEORDER_HAS_U64__ -+# define __SWAB_64_THRU_32__ -+#endif -+ -+#endif /* __NDS32_SWAB_H__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/switch_to.h linux-3.4.113/arch/nds32/include/asm/switch_to.h ---- linux-3.4.113.orig/arch/nds32/include/asm/switch_to.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/switch_to.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,18 @@ -+#ifndef __ASM_NDS32_SWITCH_TO_H -+#define __ASM_NDS32_SWITCH_TO_H -+ -+#include -+ -+/* -+ * switch_to(prev, next) should switch from task `prev' to `next' -+ * `prev' will never be the same as `next'. schedule() itself -+ * contains the memory barrier to tell GCC not to cache `current'. -+ */ -+extern struct task_struct *__switch_to(struct task_struct *, struct thread_info *, struct thread_info *); -+ -+#define switch_to( prev, next, last) \ -+do { \ -+ last = __switch_to( prev, task_thread_info( prev), task_thread_info( next)); \ -+} while (0) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/system.h linux-3.4.113/arch/nds32/include/asm/system.h ---- linux-3.4.113.orig/arch/nds32/include/asm/system.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/system.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,4 @@ -+/* FILE TO BE DELETED. DO NOT ADD STUFF HERE! */ -+#include -+#include -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/termbits.h linux-3.4.113/arch/nds32/include/asm/termbits.h ---- linux-3.4.113.orig/arch/nds32/include/asm/termbits.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/termbits.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,198 @@ -+#ifndef __ASM_NDS32_TERMBITS_H -+#define __ASM_NDS32_TERMBITS_H -+ -+typedef unsigned char cc_t; -+typedef unsigned int speed_t; -+typedef unsigned int tcflag_t; -+ -+#define NCCS 19 -+struct termios { -+ tcflag_t c_iflag; /* input mode flags */ -+ tcflag_t c_oflag; /* output mode flags */ -+ tcflag_t c_cflag; /* control mode flags */ -+ tcflag_t c_lflag; /* local mode flags */ -+ cc_t c_line; /* line discipline */ -+ cc_t c_cc[NCCS]; /* control characters */ -+}; -+ -+struct termios2 { -+ tcflag_t c_iflag; /* input mode flags */ -+ tcflag_t c_oflag; /* output mode flags */ -+ tcflag_t c_cflag; /* control mode flags */ -+ tcflag_t c_lflag; /* local mode flags */ -+ cc_t c_line; /* line discipline */ -+ cc_t c_cc[NCCS]; /* control characters */ -+ speed_t c_ispeed; /* input speed */ -+ speed_t c_ospeed; /* output speed */ -+}; -+ -+struct ktermios { -+ tcflag_t c_iflag; /* input mode flags */ -+ tcflag_t c_oflag; /* output mode flags */ -+ tcflag_t c_cflag; /* control mode flags */ -+ tcflag_t c_lflag; /* local mode flags */ -+ cc_t c_line; /* line discipline */ -+ cc_t c_cc[NCCS]; /* control characters */ -+ speed_t c_ispeed; /* input speed */ -+ speed_t c_ospeed; /* output speed */ -+}; -+ -+ -+/* c_cc characters */ -+#define VINTR 0 -+#define VQUIT 1 -+#define VERASE 2 -+#define VKILL 3 -+#define VEOF 4 -+#define VTIME 5 -+#define VMIN 6 -+#define VSWTC 7 -+#define VSTART 8 -+#define VSTOP 9 -+#define VSUSP 10 -+#define VEOL 11 -+#define VREPRINT 12 -+#define VDISCARD 13 -+#define VWERASE 14 -+#define VLNEXT 15 -+#define VEOL2 16 -+ -+/* c_iflag bits */ -+#define IGNBRK 0000001 -+#define BRKINT 0000002 -+#define IGNPAR 0000004 -+#define PARMRK 0000010 -+#define INPCK 0000020 -+#define ISTRIP 0000040 -+#define INLCR 0000100 -+#define IGNCR 0000200 -+#define ICRNL 0000400 -+#define IUCLC 0001000 -+#define IXON 0002000 -+#define IXANY 0004000 -+#define IXOFF 0010000 -+#define IMAXBEL 0020000 -+#define IUTF8 0040000 -+ -+/* c_oflag bits */ -+#define OPOST 0000001 -+#define OLCUC 0000002 -+#define ONLCR 0000004 -+#define OCRNL 0000010 -+#define ONOCR 0000020 -+#define ONLRET 0000040 -+#define OFILL 0000100 -+#define OFDEL 0000200 -+#define NLDLY 0000400 -+#define NL0 0000000 -+#define NL1 0000400 -+#define CRDLY 0003000 -+#define CR0 0000000 -+#define CR1 0001000 -+#define CR2 0002000 -+#define CR3 0003000 -+#define TABDLY 0014000 -+#define TAB0 0000000 -+#define TAB1 0004000 -+#define TAB2 0010000 -+#define TAB3 0014000 -+#define XTABS 0014000 -+#define BSDLY 0020000 -+#define BS0 0000000 -+#define BS1 0020000 -+#define VTDLY 0040000 -+#define VT0 0000000 -+#define VT1 0040000 -+#define FFDLY 0100000 -+#define FF0 0000000 -+#define FF1 0100000 -+ -+/* c_cflag bit meaning */ -+#define CBAUD 0010017 -+#define B0 0000000 /* hang up */ -+#define B50 0000001 -+#define B75 0000002 -+#define B110 0000003 -+#define B134 0000004 -+#define B150 0000005 -+#define B200 0000006 -+#define B300 0000007 -+#define B600 0000010 -+#define B1200 0000011 -+#define B1800 0000012 -+#define B2400 0000013 -+#define B4800 0000014 -+#define B9600 0000015 -+#define B19200 0000016 -+#define B38400 0000017 -+#define EXTA B19200 -+#define EXTB B38400 -+#define CSIZE 0000060 -+#define CS5 0000000 -+#define CS6 0000020 -+#define CS7 0000040 -+#define CS8 0000060 -+#define CSTOPB 0000100 -+#define CREAD 0000200 -+#define PARENB 0000400 -+#define PARODD 0001000 -+#define HUPCL 0002000 -+#define CLOCAL 0004000 -+#define CBAUDEX 0010000 -+#define BOTHER 0010000 -+#define B57600 0010001 -+#define B115200 0010002 -+#define B230400 0010003 -+#define B460800 0010004 -+#define B500000 0010005 -+#define B576000 0010006 -+#define B921600 0010007 -+#define B1000000 0010010 -+#define B1152000 0010011 -+#define B1500000 0010012 -+#define B2000000 0010013 -+#define B2500000 0010014 -+#define B3000000 0010015 -+#define B3500000 0010016 -+#define B4000000 0010017 -+#define CIBAUD 002003600000 /* input baud rate */ -+#define CMSPAR 010000000000 /* mark or space (stick) parity */ -+#define CRTSCTS 020000000000 /* flow control */ -+ -+#define IBSHIFT 16 -+ -+/* c_lflag bits */ -+#define ISIG 0000001 -+#define ICANON 0000002 -+#define XCASE 0000004 -+#define ECHO 0000010 -+#define ECHOE 0000020 -+#define ECHOK 0000040 -+#define ECHONL 0000100 -+#define NOFLSH 0000200 -+#define TOSTOP 0000400 -+#define ECHOCTL 0001000 -+#define ECHOPRT 0002000 -+#define ECHOKE 0004000 -+#define FLUSHO 0010000 -+#define PENDIN 0040000 -+#define IEXTEN 0100000 -+#define EXTPROC 0200000 -+ -+/* tcflow() and TCXONC use these */ -+#define TCOOFF 0 -+#define TCOON 1 -+#define TCIOFF 2 -+#define TCION 3 -+ -+/* tcflush() and TCFLSH use these */ -+#define TCIFLUSH 0 -+#define TCOFLUSH 1 -+#define TCIOFLUSH 2 -+ -+/* tcsetattr uses these */ -+#define TCSANOW 0 -+#define TCSADRAIN 1 -+#define TCSAFLUSH 2 -+ -+#endif /* __ASM_NDS32_TERMBITS_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/termios.h linux-3.4.113/arch/nds32/include/asm/termios.h ---- linux-3.4.113.orig/arch/nds32/include/asm/termios.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/termios.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,116 @@ -+/* -+ * linux/arch/nds32/include/asm/termios.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_TERMIOS_H -+#define __ASM_NDS32_TERMIOS_H -+ -+#include -+#include -+ -+struct winsize { -+ unsigned short ws_row; -+ unsigned short ws_col; -+ unsigned short ws_xpixel; -+ unsigned short ws_ypixel; -+}; -+ -+#define NCC 8 -+struct termio { -+ unsigned short c_iflag; /* input mode flags */ -+ unsigned short c_oflag; /* output mode flags */ -+ unsigned short c_cflag; /* control mode flags */ -+ unsigned short c_lflag; /* local mode flags */ -+ unsigned char c_line; /* line discipline */ -+ unsigned char c_cc[NCC]; /* control characters */ -+}; -+ -+#ifdef __KERNEL__ -+/* intr=^C quit=^| erase=del kill=^U -+ eof=^D vtime=\0 vmin=\1 sxtc=\0 -+ start=^Q stop=^S susp=^Z eol=\0 -+ reprint=^R discard=^U werase=^W lnext=^V -+ eol2=\0 -+*/ -+#define INIT_C_CC "\003\034\177\025\004\0\1\0\021\023\032\0\022\017\027\026\0" -+#endif -+ -+/* modem lines */ -+#define TIOCM_LE 0x001 -+#define TIOCM_DTR 0x002 -+#define TIOCM_RTS 0x004 -+#define TIOCM_ST 0x008 -+#define TIOCM_SR 0x010 -+#define TIOCM_CTS 0x020 -+#define TIOCM_CAR 0x040 -+#define TIOCM_RNG 0x080 -+#define TIOCM_DSR 0x100 -+#define TIOCM_CD TIOCM_CAR -+#define TIOCM_RI TIOCM_RNG -+#define TIOCM_OUT1 0x2000 -+#define TIOCM_OUT2 0x4000 -+#define TIOCM_LOOP 0x8000 -+ -+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */ -+ -+/* line disciplines */ -+#define N_TTY 0 -+#define N_SLIP 1 -+#define N_MOUSE 2 -+#define N_PPP 3 -+#define N_STRIP 4 -+#define N_AX25 5 -+#define N_X25 6 /* X.25 async */ -+#define N_6PACK 7 -+#define N_MASC 8 /* Reserved for Mobitex module */ -+#define N_R3964 9 /* Reserved for Simatic R3964 module */ -+#define N_PROFIBUS_FDL 10 /* Reserved for Profibus */ -+#define N_IRDA 11 /* Linux IrDa - http://irda.sourceforge.net/ */ -+#define N_SMSBLOCK 12 /* SMS block mode - for talking to GSM data cards about SMS messages */ -+#define N_HDLC 13 /* synchronous HDLC */ -+#define N_SYNC_PPP 14 -+#define N_HCI 15 /* Bluetooth HCI UART */ -+ -+#ifdef __KERNEL__ -+ -+/* -+ * Translate a "termio" structure into a "termios". Ugh. -+ */ -+#define SET_LOW_TERMIOS_BITS(termios, termio, x) { \ -+ unsigned short __tmp; \ -+ get_user(__tmp,&(termio)->x); \ -+ *(unsigned short *) &(termios)->x = __tmp; \ -+} -+ -+#define user_termio_to_kernel_termios(termios, termio) \ -+({ \ -+ SET_LOW_TERMIOS_BITS(termios, termio, c_iflag); \ -+ SET_LOW_TERMIOS_BITS(termios, termio, c_oflag); \ -+ SET_LOW_TERMIOS_BITS(termios, termio, c_cflag); \ -+ SET_LOW_TERMIOS_BITS(termios, termio, c_lflag); \ -+ copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ -+}) -+ -+/* -+ * Translate a "termios" structure into a "termio". Ugh. -+ */ -+#define kernel_termios_to_user_termio(termio, termios) \ -+({ \ -+ put_user((termios)->c_iflag, &(termio)->c_iflag); \ -+ put_user((termios)->c_oflag, &(termio)->c_oflag); \ -+ put_user((termios)->c_cflag, &(termio)->c_cflag); \ -+ put_user((termios)->c_lflag, &(termio)->c_lflag); \ -+ put_user((termios)->c_line, &(termio)->c_line); \ -+ copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ -+}) -+ -+#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) -+#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) -+ -+#define user_termios_to_kernel_termios_1(k, u) copy_from_user(k, u, sizeof(struct termios)) -+#define kernel_termios_to_user_termios_1(u, k) copy_to_user(u, k, sizeof(struct termios)) -+ -+#endif /* __KERNEL__ */ -+ -+#endif /* __ASM_NDS32_TERMIOS_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/thread_info.h linux-3.4.113/arch/nds32/include/asm/thread_info.h ---- linux-3.4.113.orig/arch/nds32/include/asm/thread_info.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/thread_info.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,145 @@ -+/* -+ * linux/arch/nds32/include/asm/thread_info.h -+ * -+ * Copyright (C) 2002 Russell King. -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef __ASM_NDS32_THREAD_INFO_H -+#define __ASM_NDS32_THREAD_INFO_H -+ -+#ifdef __KERNEL__ -+ -+#define THREAD_SHIFT (13) -+#define THREAD_SIZE (1 << THREAD_SHIFT) -+ -+#ifndef __ASSEMBLY__ -+ -+struct task_struct; -+struct exec_domain; -+ -+#include -+#include -+ -+ -+typedef struct { -+ unsigned long seg; -+} mm_segment_t; -+//typedef unsigned long mm_segment_t; -+ -+struct cpu_context_save { -+ unsigned long r6; -+ unsigned long r7; -+ unsigned long r8; -+ unsigned long r9; -+ unsigned long r10; -+ unsigned long r11; -+ unsigned long r12; -+ unsigned long r13; -+ unsigned long r14; -+ unsigned long fp; -+ unsigned long pc; -+}; -+ -+/* -+ * low level task data that entry.S needs immediate access to. -+ * __switch_to() assumes cpu_context follows immediately after cpu_domain. -+ */ -+struct thread_info { -+ unsigned long flags; /* low level flags */ -+ __s32 preempt_count; /* 0 => preemptable, <0 => bug */ -+ mm_segment_t addr_limit; /* address limit */ -+ struct task_struct *task; /* main task structure */ -+ struct exec_domain *exec_domain; /* execution domain */ -+ __u32 cpu; /* cpu */ -+ struct cpu_context_save* sp_save; /* cpu context */ -+ struct restart_block restart_block; -+}; -+ -+#define INIT_THREAD_INFO(tsk) \ -+{ \ -+ .task = &tsk, \ -+ .exec_domain = &default_exec_domain, \ -+ .flags = 0, \ -+ .cpu = 0, \ -+ .preempt_count = 1, \ -+ .addr_limit = KERNEL_DS, \ -+ .restart_block = { \ -+ .fn = do_no_restart_syscall, \ -+ }, \ -+} -+ -+#define init_thread_info (init_thread_union.thread_info) -+#define init_stack (init_thread_union.stack) -+ -+ -+/* -+ * how to get the thread information struct from C -+ */ -+static inline struct thread_info *current_thread_info(void) __attribute_const__; -+ -+static inline struct thread_info *current_thread_info(void) -+{ -+ register unsigned long sp asm ("$sp"); //M Tom asm -> __asm__ __volatile__ -+ return (struct thread_info *)(sp & ~(THREAD_SIZE - 1)); -+} -+ -+#define get_thread_info(ti) get_task_struct((ti)->task) -+#define put_thread_info(ti) put_task_struct((ti)->task) -+ -+#define thread_saved_pc(tsk) \ -+ ((unsigned long)(task_thread_info(tsk)->sp_save->pc)) -+#define thread_saved_fp(tsk) \ -+ ((unsigned long)(task_thread_info(tsk)->sp_save->fp)) -+#endif -+ -+#define THREAD_SIZE_ORDER (1) -+/* -+ * We use bit 30 of the preempt_count to indicate that kernel -+ * preemption is occuring. See include/asm-arm/hardirq.h. -+ */ -+#define PREEMPT_ACTIVE 0x40000000 -+ -+/* -+ * thread information flags: -+ * TIF_SYSCALL_TRACE - syscall trace active -+ * TIF_NOTIFY_RESUME - resumption notification requested -+ * TIF_SIGPENDING - signal pending -+ * TIF_NEED_RESCHED - rescheduling necessary -+ * TIF_USEDFPU - FPU was used by this task this quantum (SMP) -+ * TIF_POLLING_NRFLAG - true if poll_idle() is polling TIF_NEED_RESCHED -+ * TIF_USEDAUDIO - Audio has been used by this task and no need to init the regs -+ */ -+#define TIF_SIGPENDING 1 -+#define TIF_NEED_RESCHED 2 -+#define TIF_SINGLESTEP 3 -+#define TIF_NOTIFY_RESUME 5 -+#define TIF_SYSCALL_TRACE 8 -+#define TIF_RESTORE_SIGMASK 9 -+#define TIF_USEDFPU 16 -+#define TIF_POLLING_NRFLAG 17 -+#define TIF_MEMDIE 18 -+#define TIF_FREEZE 19 -+#define TIF_USEDAUDIO 20 -+ -+#define _TIF_SIGPENDING (1 << TIF_SIGPENDING) -+#define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) -+#define _TIF_SINGLESTEP (1 << TIF_SINGLESTEP) -+#define _TIF_NOTIFY_RESUME (1 << TIF_NOTIFY_RESUME) -+#define _TIF_SYSCALL_TRACE (1 << TIF_SYSCALL_TRACE) -+#define _TIF_RESTORE_SIGMASK (1 << TIF_RESTORE_SIGMASK) -+#define _TIF_POLLING_NRFLAG (1 << TIF_POLLING_NRFLAG) -+#define _TIF_FREEZE (1 << TIF_FREEZE) -+ -+/* -+ * Change these and you break ASM code in entry-common.S -+ */ -+#define _TIF_WORK_MASK 0x000000ff -+#define _TIF_WORK_SYSCALL_ENTRY (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP) -+#define _TIF_WORK_SYSCALL_LEAVE (_TIF_SYSCALL_TRACE | _TIF_SINGLESTEP) -+ -+#endif /* __KERNEL__ */ -+#endif /* __ASM_NDS32_THREAD_INFO_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/timer.h linux-3.4.113/arch/nds32/include/asm/timer.h ---- linux-3.4.113.orig/arch/nds32/include/asm/timer.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/timer.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,94 @@ -+/* -+ * include/arch/nds32/include/asm/timer.h -+ * -+ * Faraday FTTMR010 Timer Device Driver Interface -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Note -+ * -+ * As IP_COUNT might be greater than one, timer ID is computed as follows: -+ * id=0~2 : Timer 1~3 of the first FTTMR010 IP -+ * id=3~5 : Timer 1~3 of the second FTTMR010 IP -+ * ... -+ * Therefore: -+ * (id / 3) : Compute which IP -+ * (id % 3) : Compute which timer in this IP -+ * Notice: -+ * For simplicity's sake, all code does not check for invalid timer id -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/14/2005 Created, heavily modified from Faraday CPE platform code. -+ */ -+ -+ -+#ifndef __FARADAY_TIMER_FTTMR010_HEADER__ -+#define __FARADAY_TIMER_FTTMR010_HEADER__ -+ -+/* -+ * Definition of register offsets -+ */ -+ -+#define TIMER1_COUNT 0x0 -+#define TIMER1_LOAD 0x4 -+#define TIMER1_MATCH1 0x8 -+#define TIMER1_MATCH2 0xC -+ -+#define TIMER2_COUNT 0x10 -+#define TIMER2_LOAD 0x14 -+#define TIMER2_MATCH1 0x18 -+#define TIMER2_MATCH2 0x1C -+ -+#define TIMER3_COUNT 0x20 -+#define TIMER3_LOAD 0x24 -+#define TIMER3_MATCH1 0x28 -+#define TIMER3_MATCH2 0x2C -+ -+#define TIMER_TMCR 0x30 -+#define TIMER_INTRSTATE 0x34 -+#define TIMER_INTRMASK 0x38 -+ -+/* Each timer's register address is offset by 0x10 */ -+#define TIMER_OFFSET 0x10 -+ -+/* -+ * Definition of TMCR bits -+ */ -+ -+#define TM1ENABLE 1 -+#define TM1CLOCK (1<<1) -+#define TM1OFENABLE (1<<2) -+ -+#define TM2ENABLE (1<<3) -+#define TM2CLOCK (1<<4) -+#define TM2OFENABLE (1<<5) -+ -+#define TM3ENABLE (1<<6) -+#define TM3CLOCK (1<<7) -+#define TM3OFENABLE (1<<8) -+ -+#define TM1UPDOWN (1<<9) -+#define TM2UPDOWN (1<<10) -+#define TM3UPDOWN (1<<11) -+ -+ -+#define TM1MATCH1 (1 << 0) -+#define TM1MATCH2 (1 << 1) -+#define TM1OVERFLOW (1 << 2) -+#define TM2MATCH1 (1 << 3) -+#define TM2MATCH2 (1 << 4) -+#define TM2OVERFLOW (1 << 5) -+#define TM3MATCH1 (1 << 6) -+#define TM3MATCH2 (1 << 7) -+#define TM3OVERFLOW (1 << 8) -+ -+struct sys_timer; -+extern struct sys_timer platform_timer; -+ -+#endif // __FARADAY_TIMER_FTTMR010_HEADER__ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/timex.h linux-3.4.113/arch/nds32/include/asm/timex.h ---- linux-3.4.113.orig/arch/nds32/include/asm/timex.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/timex.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * linux/arch/nds32/include/asm/timex.h -+ * -+ * Copyright (C) 1997,1998 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Architecture Specific TIME specifications -+ */ -+#ifndef _ASMNDS32_TIMEX_H -+#define _ASMNDS32_TIMEX_H -+ -+#ifndef __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ -+#define __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ -+ -+#include -+ -+#ifndef CLOCK_TICK_RATE -+#define CLOCK_TICK_RATE (TIMER_CLK_IN) -+#endif -+ -+#endif /* __FARADAY_PLATFORM_INDEPENDENT_TIMEX_HEADER__ */ -+ -+typedef unsigned long cycles_t; -+ -+extern cycles_t cacheflush_time; -+ -+static inline cycles_t get_cycles (void) -+{ -+ return 0; -+} -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/tlbflush.h linux-3.4.113/arch/nds32/include/asm/tlbflush.h ---- linux-3.4.113.orig/arch/nds32/include/asm/tlbflush.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/tlbflush.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,80 @@ -+/* -+ * linux/arch/nds32/include/asm/tlbflush.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_TLBFLUSH_H -+#define _ASMNDS32_TLBFLUSH_H -+ -+#include -+#include -+#include -+ -+static inline void local_flush_tlb_all(void) -+{ -+ asm("tlbop FLUA\n"); -+ __nds32__isb(); -+} -+static inline void local_flush_tlb_mm(struct mm_struct *mm) -+{ -+ asm("tlbop FLUA\n"); -+ __nds32__isb(); -+} -+static inline void local_flush_tlb_kernel_range(unsigned long start, -+ unsigned long end) -+{ -+ while(start < end) { -+ asm("tlbop %0, INV"::"r" (start)); -+ __nds32__isb(); -+ start += PAGE_SIZE; -+ } -+} -+ -+#ifndef CONFIG_CPU_NO_CONTEXT_ID -+void local_flush_tlb_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end); -+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); -+#else -+static inline void local_flush_tlb_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+ if ((end - start) > 0x400000) { -+ asm("tlbop FLUA"); -+ __nds32__isb(); -+ return ; -+ } -+ while(start < end) { -+ asm("tlbop %0, INV"::"r" (start)); -+ __nds32__isb(); -+ start += PAGE_SIZE; -+ } -+} -+ -+static inline void local_flush_tlb_page(struct vm_area_struct *vma, -+ unsigned long addr) -+{ -+ asm("tlbop %0, INV"::"r" (addr)); -+ __nds32__isb(); -+} -+#endif -+ -+#ifndef CONFIG_SMP -+#define flush_tlb_all local_flush_tlb_all -+#define flush_tlb_mm local_flush_tlb_mm -+#define flush_tlb_range local_flush_tlb_range -+#define flush_tlb_page local_flush_tlb_page -+#define flush_tlb_kernel_range local_flush_tlb_kernel_range -+#else -+void flush_tlb_all(void); -+void flush_tlb_mm(struct mm_struct *mm); -+void flush_tlb_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end); -+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr); -+void flush_tlb_kernel_range(unsigned long start, unsigned long end); -+#endif -+ -+void update_mmu_cache(struct vm_area_struct *vma, -+ unsigned long address, pte_t* pte); -+void tlb_migrate_finish(struct mm_struct *mm); -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/tlb.h linux-3.4.113/arch/nds32/include/asm/tlb.h ---- linux-3.4.113.orig/arch/nds32/include/asm/tlb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/tlb.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,30 @@ -+/* -+ * linux/arch/nds32/include/asm/tlb.h -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+ -+#ifndef __ASMNDS32_TLB_H -+#define __ASMNDS32_TLB_H -+ -+#define tlb_start_vma(tlb,vma) \ -+ do { \ -+ if (!tlb->fullmm) \ -+ flush_cache_range(vma, vma->vm_start, vma->vm_end); \ -+ } while (0) -+ -+#define tlb_end_vma(tlb,vma) \ -+ do { \ -+ if(!tlb->fullmm) \ -+ flush_tlb_range(vma, vma->vm_start, vma->vm_end); \ -+ } while (0) -+ -+#define __tlb_remove_tlb_entry(tlb, pte, addr) do { } while (0) -+ -+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm) -+ -+#include -+ -+#define __pte_free_tlb(tlb, pte, addr) pte_free((tlb)->mm, pte) -+#define __pmd_free_tlb(tlb, pmd, addr) pmd_free((tln)->mm, pmd) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/topology.h linux-3.4.113/arch/nds32/include/asm/topology.h ---- linux-3.4.113.orig/arch/nds32/include/asm/topology.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/topology.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,11 @@ -+/* -+ * linux/arch/nds32/include/asm/topology.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASM_NDS32_TOPOLOGY_H -+#define _ASM_NDS32_TOPOLOGY_H -+ -+#include -+ -+#endif /* _ASM_NDS32_TOPOLOGY_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/traps.h linux-3.4.113/arch/nds32/include/asm/traps.h ---- linux-3.4.113.orig/arch/nds32/include/asm/traps.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/traps.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * linux/arch/nds32/include/asm/traps.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_TRAP_H -+#define _ASMNDS32_TRAP_H -+ -+#include -+ -+struct undef_hook { -+ struct list_head node; -+ u32 instr_mask; -+ u32 instr_val; -+ u32 cpsr_mask; -+ u32 cpsr_val; -+ int (*fn)(struct pt_regs *regs, unsigned int instr); -+}; -+ -+void register_undef_hook(struct undef_hook *hook); -+void unregister_undef_hook(struct undef_hook *hook); -+ -+extern void __init early_trap_init(void); -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/types.h linux-3.4.113/arch/nds32/include/asm/types.h ---- linux-3.4.113.orig/arch/nds32/include/asm/types.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/types.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,16 @@ -+#ifndef __ASM_NDS32_TYPES_H -+#define __ASM_NDS32_TYPES_H -+ -+#include -+ -+/* -+ * These aren't exported outside the kernel to avoid name space clashes -+ */ -+#ifdef __KERNEL__ -+ -+#define BITS_PER_LONG 32 -+ -+#endif /* __KERNEL__ */ -+ -+#endif -+ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/uaccess.h linux-3.4.113/arch/nds32/include/asm/uaccess.h ---- linux-3.4.113.orig/arch/nds32/include/asm/uaccess.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/uaccess.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,428 @@ -+/* -+ * linux/arch/nds32/include/asm/uaccess.h -+ * -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+#ifndef _ASMANDES_UACCESS_H -+#define _ASMANDES_UACCESS_H -+ -+/* -+ * User space memory access functions -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define VERIFY_READ 0 -+#define VERIFY_WRITE 1 -+ -+/* -+ * The exception table consists of pairs of addresses: the first is the -+ * address of an instruction that is allowed to fault, and the second is -+ * the address at which the program should continue. No registers are -+ * modified, so it is entirely up to the continuation code to figure out -+ * what to do. -+ * -+ * All the routines below use bits of fixup code that are out of line -+ * with the main instruction path. This means when everything is well, -+ * we don't even have to jump over them. Further, they do not intrude -+ * on our cache or tlb entries. -+ */ -+ -+struct exception_table_entry -+{ -+ unsigned long insn, fixup; -+}; -+ -+extern int fixup_exception(struct pt_regs *regs); -+ -+#define KERNEL_DS ((mm_segment_t) { ~0UL }) -+#define USER_DS ((mm_segment_t) {TASK_SIZE - 1}) -+ -+#define get_ds() (KERNEL_DS) -+#define get_fs() (current_thread_info()->addr_limit) -+ -+static inline void set_fs (mm_segment_t fs) -+{ -+ current_thread_info()->addr_limit = fs; -+} -+ -+#define segment_eq(a, b) ((a.seg) == (b.seg)) -+ -+#define __range_ok(addr, size) (size <= get_fs().seg && addr <= (get_fs().seg -size)) -+ -+#define access_ok(type, addr, size) \ -+ __range_ok((unsigned long)addr, (unsigned long)size) -+/* -+ * Single-value transfer routines. They automatically use the right -+ * size if we just have the right pointer type. Note that the functions -+ * which read from user space (*get_*) need to take care not to leak -+ * kernel data even if the calling code is buggy and fails to check -+ * the return value. This means zeroing out the destination variable -+ * or buffer on error. Normally this is done out of line by the -+ * fixup code, but there are a few places where it intrudes on the -+ * main code path. When we only write to user space, there is no -+ * problem. -+ * -+ * The "__xxx" versions of the user access functions do not verify the -+ * address space - it must have been done previously with a separate -+ * "access_ok()" call. -+ * -+ * The "xxx_error" versions set the third argument to EFAULT if an -+ * error occurs, and leave it unchanged on success. Note that these -+ * versions are void (ie, don't return a value as such). -+ */ -+ -+extern int __get_user_1(void *); -+extern int __get_user_2(void *); -+extern int __get_user_4(void *); -+extern int __get_user_8(void *); -+extern int __get_user_bad(void); -+ -+#define __get_user_x(__r2,__p,__e,__s,__i...) \ -+ __asm__ __volatile__ ( \ -+ __asmeq("%0", "$r0") __asmeq("%1", "$r2") \ -+ "bal __get_user_" #__s \ -+ : "=&r" (__e), "=r" (__r2) \ -+ : "0" (__p) \ -+ : __i, "cc") -+ -+#define get_user(x,p) \ -+ ({ \ -+ const register typeof(*(p)) __user *__p asm("$r0") = (p);\ -+ register unsigned long __r2 asm("$r2"); \ -+ register int __e asm("$r0"); \ -+ switch (sizeof(*(__p))) { \ -+ case 1: \ -+ __get_user_x(__r2, __p, __e, 1, "$lp"); \ -+ break; \ -+ case 2: \ -+ __get_user_x(__r2, __p, __e, 2, "$r3", "$lp"); \ -+ break; \ -+ case 4: \ -+ __get_user_x(__r2, __p, __e, 4, "$lp"); \ -+ break; \ -+ case 8: \ -+ __get_user_x(__r2, __p, __e, 8, "$lp"); \ -+ break; \ -+ default: __e = __get_user_bad(); break; \ -+ } \ -+ x = (typeof(*(p))) __r2; \ -+ __e; \ -+ }) -+ -+#define __get_user(x,ptr) \ -+({ \ -+ long __gu_err = 0; \ -+ __get_user_err((x),(ptr),__gu_err); \ -+ __gu_err; \ -+}) -+ -+#define __get_user_error(x,ptr,err) \ -+({ \ -+ __get_user_err((x),(ptr),err); \ -+ (void) 0; \ -+}) -+ -+#define __get_user_err(x,ptr,err) \ -+do { \ -+ unsigned long __gu_addr = (unsigned long)(ptr); \ -+ unsigned long __gu_val; \ -+ __chk_user_ptr(ptr); \ -+ switch (sizeof(*(ptr))) { \ -+ case 1: __get_user_asm_byte(__gu_val,__gu_addr,err); break; \ -+ case 2: __get_user_asm_half(__gu_val,__gu_addr,err); break; \ -+ case 4: __get_user_asm_word(__gu_val,__gu_addr,err); break; \ -+ default: (__gu_val) = __get_user_bad(); \ -+ } \ -+ (x) = (__typeof__(*(ptr)))__gu_val; \ -+} while (0) -+ -+#define __get_user_asm_byte(x,addr,err) \ -+ __asm__ __volatile__( \ -+ "1: lbi %1,[%2]\n" \ -+ "2:\n" \ -+ " .section .fixup,\"ax\"\n" \ -+ " .align 2\n" \ -+ "3: move %0, %3\n" \ -+ " move %1, #0\n" \ -+ " b 2b\n" \ -+ " .previous\n" \ -+ " .section __ex_table,\"a\"\n" \ -+ " .align 3\n" \ -+ " .long 1b, 3b\n" \ -+ " .previous" \ -+ : "+r" (err), "=&r" (x) \ -+ : "r" (addr), "i" (-EFAULT) \ -+ : "cc") -+ -+#ifndef __NDS32_EB__ -+#define __get_user_asm_half(x,__gu_addr,err) \ -+({ \ -+ unsigned long __b1, __b2; \ -+ __get_user_asm_byte(__b1, __gu_addr, err); \ -+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \ -+ (x) = __b1 | (__b2 << 8); \ -+}) -+#else -+#define __get_user_asm_half(x,__gu_addr,err) \ -+({ \ -+ unsigned long __b1, __b2; \ -+ __get_user_asm_byte(__b1, __gu_addr, err); \ -+ __get_user_asm_byte(__b2, __gu_addr + 1, err); \ -+ (x) = (__b1 << 8) | __b2; \ -+}) -+#endif -+ -+#define __get_user_asm_word(x,addr,err) \ -+ __asm__ __volatile__( \ -+ "1: lwi %1,[%2]\n" \ -+ "2:\n" \ -+ " .section .fixup,\"ax\"\n" \ -+ " .align 2\n" \ -+ "3: move %0, %3\n" \ -+ " move %1, #0\n" \ -+ " b 2b\n" \ -+ " .previous\n" \ -+ " .section __ex_table,\"a\"\n" \ -+ " .align 3\n" \ -+ " .long 1b, 3b\n" \ -+ " .previous" \ -+ : "+r" (err), "=&r" (x) \ -+ : "r" (addr), "i" (-EFAULT) \ -+ : "cc") -+ -+extern int __put_user_1(void *, unsigned int); -+extern int __put_user_2(void *, unsigned int); -+extern int __put_user_4(void *, unsigned int); -+extern int __put_user_8(void *, unsigned long long); -+extern int __put_user_bad(void); -+ -+#ifdef _GCC444 -+#define __put_user_x(__r2,__p,__e,__s) \ -+ __asm__ __volatile__ ( \ -+ __asmeq("%0", "$r0") __asmeq("%2", "$r2") \ -+ "bal __put_user_" #__s \ -+ : "=&r" (__e) \ -+ : "0" (__p), "r" (__r2) \ -+ : "$p0", "$lp", "cc") -+#else -+#define __put_user_x(__r2,__p,__e,__s) \ -+ __asm__ __volatile__ ( \ -+ __asmeq("%0", "$r0") __asmeq("%2", "$r2") \ -+ "bal __put_user_" #__s \ -+ : "=&r" (__e) \ -+ : "0" (__p), "r" (__r2) \ -+ : "$r26", "$lp", "cc") -+#endif -+ -+#define put_user(x,p) \ -+ ({ \ -+ const register typeof(*(p)) __r2 asm("$r2") = (x); \ -+ const register typeof(*(p)) __user *__p asm("$r0") = (p);\ -+ register int __e asm("$r0"); \ -+ switch (sizeof(*(__p))) { \ -+ case 1: \ -+ __put_user_x(__r2, __p, __e, 1); \ -+ break; \ -+ case 2: \ -+ __put_user_x(__r2, __p, __e, 2); \ -+ break; \ -+ case 4: \ -+ __put_user_x(__r2, __p, __e, 4); \ -+ break; \ -+ case 8: \ -+ __put_user_x(__r2, __p, __e, 8); \ -+ break; \ -+ default: __e = __put_user_bad(); break; \ -+ } \ -+ __e; \ -+ }) -+ -+#define __put_user(x,ptr) \ -+({ \ -+ long __pu_err = 0; \ -+ __put_user_err((x),(ptr),__pu_err); \ -+ __pu_err; \ -+}) -+ -+#define __put_user_error(x,ptr,err) \ -+({ \ -+ __put_user_err((x),(ptr),err); \ -+ (void) 0; \ -+}) -+ -+#define __put_user_err(x,ptr,err) \ -+do { \ -+ unsigned long __pu_addr = (unsigned long)(ptr); \ -+ __typeof__(*(ptr)) __pu_val = (x); \ -+ __chk_user_ptr(ptr); \ -+ switch (sizeof(*(ptr))) { \ -+ case 1: __put_user_asm_byte(__pu_val,__pu_addr,err); break; \ -+ case 2: __put_user_asm_half(__pu_val,__pu_addr,err); break; \ -+ case 4: __put_user_asm_word(__pu_val,__pu_addr,err); break; \ -+ case 8: __put_user_asm_dword(__pu_val,__pu_addr,err); break; \ -+ default: __put_user_bad(); \ -+ } \ -+} while (0) -+ -+#define __put_user_asm_byte(x,__pu_addr,err) \ -+ __asm__ __volatile__( \ -+ "1: sbi %1,[%2]\n" \ -+ "2:\n" \ -+ " .section .fixup,\"ax\"\n" \ -+ " .align 2\n" \ -+ "3: move %0, %3\n" \ -+ " b 2b\n" \ -+ " .previous\n" \ -+ " .section __ex_table,\"a\"\n" \ -+ " .align 3\n" \ -+ " .long 1b, 3b\n" \ -+ " .previous" \ -+ : "+r" (err) \ -+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ -+ : "cc") -+ -+#ifndef __NDS32_EB__ -+#define __put_user_asm_half(x,__pu_addr,err) \ -+({ \ -+ unsigned long __temp = (unsigned long)(x); \ -+ __put_user_asm_byte(__temp, __pu_addr, err); \ -+ __put_user_asm_byte(__temp >> 8, __pu_addr + 1, err); \ -+}) -+#else -+#define __put_user_asm_half(x,__pu_addr,err) \ -+({ \ -+ unsigned long __temp = (unsigned long)(x); \ -+ __put_user_asm_byte(__temp >> 8, __pu_addr, err); \ -+ __put_user_asm_byte(__temp, __pu_addr + 1, err); \ -+}) -+#endif -+ -+#define __put_user_asm_word(x,__pu_addr,err) \ -+ __asm__ __volatile__( \ -+ "1: swi %1,[%2]\n" \ -+ "2:\n" \ -+ " .section .fixup,\"ax\"\n" \ -+ " .align 2\n" \ -+ "3: move %0, %3\n" \ -+ " b 2b\n" \ -+ " .previous\n" \ -+ " .section __ex_table,\"a\"\n" \ -+ " .align 3\n" \ -+ " .long 1b, 3b\n" \ -+ " .previous" \ -+ : "+r" (err) \ -+ : "r" (x), "r" (__pu_addr), "i" (-EFAULT) \ -+ : "cc") -+ -+#ifdef __NDS32_EB__ -+#define __reg_oper0 "%H2" -+#define __reg_oper1 "%L2" -+#else -+#define __reg_oper0 "%L2" -+#define __reg_oper1 "%H2" -+#endif -+ -+#define __put_user_asm_dword(x, __pu_addr, __pu_err) \ -+ __asm__ __volatile__ ( \ -+ "\n1:\tswi " __reg_oper0 ",[%1]\n" \ -+ "\n2:\tswi " __reg_oper1 ",[%1+4]\n" \ -+ "3:\n" \ -+ " .section .fixup,\"ax\"\n" \ -+ " .align 2\n" \ -+ "4: move %0, %3\n" \ -+ " b 3b\n" \ -+ " .previous\n" \ -+ " .section __ex_table,\"a\"\n" \ -+ " .align 3\n" \ -+ " .long 1b, 4b\n" \ -+ " .long 2b, 4b\n" \ -+ " .previous" \ -+ : "+r"(__pu_err) \ -+ : "r"(__pu_addr), "r"(x), "i"(-EFAULT) \ -+ : "cc") -+extern unsigned long __arch_copy_from_user(void *to, const void __user *from, unsigned long n); -+extern unsigned long __arch_copy_to_user(void __user *to, const void *from, unsigned long n); -+extern unsigned long __arch_clear_user(void __user *addr, unsigned long n); -+extern unsigned long __arch_strncpy_from_user(char *to, const char __user *from, unsigned long count); -+extern unsigned long __arch_strnlen_user(const char __user *s, long n); -+ -+static inline unsigned long copy_from_user(void *to, const void __user *from, unsigned long n) -+{ -+ if (access_ok(VERIFY_READ, from, n)) -+ n = __arch_copy_from_user(to, from, n); -+ else /* security hole - plug it */ -+ memzero(to, n); -+ return n; -+} -+ -+static inline unsigned long __copy_from_user(void *to, const void __user *from, unsigned long n) -+{ -+ return __arch_copy_from_user(to, from, n); -+} -+ -+static inline unsigned long copy_to_user(void __user *to, const void *from, unsigned long n) -+{ -+ if (access_ok(VERIFY_WRITE, to, n)) -+ n = __arch_copy_to_user(to, from, n); -+ return n; -+} -+ -+static inline unsigned long __copy_to_user(void __user *to, const void *from, unsigned long n) -+{ -+ return __arch_copy_to_user(to, from, n); -+} -+ -+#define __copy_to_user_inatomic __copy_to_user -+#define __copy_from_user_inatomic __copy_from_user -+ -+static inline unsigned long clear_user (void __user *to, unsigned long n) -+{ -+ if (access_ok(VERIFY_WRITE, to, n)) -+ n = __arch_clear_user(to, n); -+ return n; -+} -+ -+static inline unsigned long __clear_user (void __user *to, unsigned long n) -+{ -+ return __arch_clear_user(to, n); -+} -+ -+/* -+ * We check the flags of vma here before __arch_strncpy_from_user(). -+ * An alternative way to do it is using lwup instruction in __arch_strncpy_from_user(). -+ * TODO: Should perform performance evaluation of the two. -+ */ -+static inline long strncpy_from_user (char *dst, const char __user *src, long count) -+{ -+ long res = -EFAULT; -+ if (access_ok(VERIFY_READ, src, 1)) -+ res = __arch_strncpy_from_user(dst, src, count); -+ return res; -+} -+ -+static inline long __strncpy_from_user (char *dst, const char __user *src, long count) -+{ -+ return __arch_strncpy_from_user(dst, src, count); -+} -+ -+#define strlen_user(s) strnlen_user(s, ~0UL >> 1) -+ -+static inline long strnlen_user(const char __user *s, long n) -+{ -+ unsigned long res = 0; -+ -+ if (segment_eq(get_fs(),KERNEL_DS) || ((unsigned long)s < get_fs().seg)) -+ res = __arch_strnlen_user(s, n); -+ -+ return res; -+} -+#endif /* _ASMNDS32_UACCESS_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/ucontext.h linux-3.4.113/arch/nds32/include/asm/ucontext.h ---- linux-3.4.113.orig/arch/nds32/include/asm/ucontext.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/ucontext.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,17 @@ -+/* -+ * linux/arch/nds32/include/asm/ucontext.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _ASMNDS32_UCONTEXT_H -+#define _ASMNDS32_UCONTEXT_H -+ -+struct ucontext { -+ unsigned long uc_flags; -+ struct ucontext *uc_link; -+ stack_t uc_stack; -+ struct sigcontext uc_mcontext; -+ sigset_t uc_sigmask; /* mask last for extensibility */ -+}; -+ -+#endif /* !_ASMNDS32_UCONTEXT_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/unaligned.h linux-3.4.113/arch/nds32/include/asm/unaligned.h ---- linux-3.4.113.orig/arch/nds32/include/asm/unaligned.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/unaligned.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,24 @@ -+/* -+ * linux/arch/nds32/include/asm/unaligned.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef __ASM_NDS32_UNALIGNED_H -+#define __ASM_NDS32_UNALIGNED_H -+ -+#include -+#include -+#include -+ -+/* -+ * Select endianness -+ */ -+#if defined(__NDS32_EB__) -+#define get_unaligned __get_unaligned_be -+#define put_unaligned __put_unaligned_be -+#else -+#define get_unaligned __get_unaligned_le -+#define put_unaligned __put_unaligned_le -+#endif -+ -+#endif /* __ASM_NDS32_UNALIGNED_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/uncompress.h linux-3.4.113/arch/nds32/include/asm/uncompress.h ---- linux-3.4.113.orig/arch/nds32/include/asm/uncompress.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/uncompress.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,65 @@ -+/* -+ * linux/arch/nds32/include/asm/uncompress.h -+ * -+ * Faraday Linux Boot Loader UART (FTUART010) Routines -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * Note -+ * -+ * The first UART (FTUART010) in the system is used for dumping debug messages. -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/21/2005 Created. Heavily modified from Faraday CPE port. -+ */ -+ -+#include -+ -+#ifdef CONFIG_PLAT_AG102 -+#define UART_PA_BASE 0x94200000 -+#else -+#define UART_PA_BASE 0x99600000 -+#endif -+ -+#define arch_decomp_setup() -+#define arch_decomp_wdog() -+ -+#ifndef STANDALONE_DEBUG -+#define putstr debug_puts -+#endif -+ -+#define SERIAL_THR 0x00 -+#define SERIAL_LSR 0x14 -+#define SERIAL_LSR_THRE 0x20 -+ -+static inline void uncompress_puts(const char *s) -+{ -+ volatile unsigned *status = (volatile unsigned *)(UART_PA_BASE+SERIAL_LSR); -+ while (*s) { -+ while ((*status & SERIAL_LSR_THRE)==0); -+ -+ *(volatile unsigned*)(UART_PA_BASE+SERIAL_THR) = (unsigned)*s; -+ -+ if (*s == '\n') { -+ while ((*status & SERIAL_LSR_THRE)==0); -+ *(volatile unsigned*)(UART_PA_BASE+SERIAL_THR) = '\r'; -+ } -+ s++; -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/unistd.h linux-3.4.113/arch/nds32/include/asm/unistd.h ---- linux-3.4.113.orig/arch/nds32/include/asm/unistd.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/unistd.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,468 @@ -+/* -+ * linux/arch/nds32/include/asm/unistd.h -+ * -+ * Copyright (C) 2001-2003 Russell King -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ * -+ * Please forward _all_ changes to this file to rmk@arm.linux.org.uk, -+ * no matter what the change is. Thanks! -+ */ -+/* ============================================================================ -+ * -+ * linux/arch/nds32/include/asm/unistd.h -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is syscall scheme for Andes NDS32 architecture. -+ * -+ * Revision History: -+ * -+ * Jul.07.2007 Original from Shawn and Tom, refined by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+ -+#ifndef __ASM_NDS32_UNISTD_H -+#define __ASM_NDS32_UNISTD_H -+ -+#define __NR_SYSCALL_BASE 0x5000 -+#define __NR_NDS32_BASE 0x7000 -+/* -+ * This file contains the system call numbers. -+ */ -+ -+#define __NR_restart_syscall (__NR_SYSCALL_BASE+ 0) -+#define __NR_exit (__NR_SYSCALL_BASE+ 1) -+#define __NR_fork (__NR_SYSCALL_BASE+ 2) -+#define __NR_read (__NR_SYSCALL_BASE+ 3) -+#define __NR_write (__NR_SYSCALL_BASE+ 4) -+#define __NR_open (__NR_SYSCALL_BASE+ 5) -+#define __NR_close (__NR_SYSCALL_BASE+ 6) -+#define __NR_waitpid (__NR_SYSCALL_BASE+ 7) -+ /* 7 was sys_waitpid */ -+#define __NR_creat (__NR_SYSCALL_BASE+ 8) -+#define __NR_link (__NR_SYSCALL_BASE+ 9) -+#define __NR_unlink (__NR_SYSCALL_BASE+ 10) -+#define __NR_execve (__NR_SYSCALL_BASE+ 11) -+#define __NR_chdir (__NR_SYSCALL_BASE+ 12) -+#define __NR_time (__NR_SYSCALL_BASE+ 13) -+#define __NR_mknod (__NR_SYSCALL_BASE+ 14) -+#define __NR_chmod (__NR_SYSCALL_BASE+ 15) -+#define __NR_lchown (__NR_SYSCALL_BASE+ 16) -+ /* 17 was sys_break */ -+ /* 18 was sys_oldstat */ -+#define __NR_lseek (__NR_SYSCALL_BASE+ 19) -+#define __NR_getpid (__NR_SYSCALL_BASE+ 20) -+#define __NR_mount (__NR_SYSCALL_BASE+ 21) -+#define __NR_umount (__NR_SYSCALL_BASE+ 22) -+#define __NR_setuid (__NR_SYSCALL_BASE+ 23) -+#define __NR_getuid (__NR_SYSCALL_BASE+ 24) -+#define __NR_stime (__NR_SYSCALL_BASE+ 25) -+#define __NR_ptrace (__NR_SYSCALL_BASE+ 26) -+#define __NR_alarm (__NR_SYSCALL_BASE+ 27) -+ /* 28 was sys_oldfstat */ -+#define __NR_pause (__NR_SYSCALL_BASE+ 29) -+#define __NR_utime (__NR_SYSCALL_BASE+ 30) -+ /* 31 was sys_stty */ -+ /* 32 was sys_gtty */ -+#define __NR_access (__NR_SYSCALL_BASE+ 33) -+#define __NR_nice (__NR_SYSCALL_BASE+ 34) -+ /* 35 was sys_ftime */ -+#define __NR_sync (__NR_SYSCALL_BASE+ 36) -+#define __NR_kill (__NR_SYSCALL_BASE+ 37) -+#define __NR_rename (__NR_SYSCALL_BASE+ 38) -+#define __NR_mkdir (__NR_SYSCALL_BASE+ 39) -+#define __NR_rmdir (__NR_SYSCALL_BASE+ 40) -+#define __NR_dup (__NR_SYSCALL_BASE+ 41) -+#define __NR_pipe (__NR_SYSCALL_BASE+ 42) -+#define __NR_times (__NR_SYSCALL_BASE+ 43) -+ /* 44 was sys_prof */ -+#define __NR_brk (__NR_SYSCALL_BASE+ 45) -+#define __NR_setgid (__NR_SYSCALL_BASE+ 46) -+#define __NR_getgid (__NR_SYSCALL_BASE+ 47) -+ /* 48 was sys_signal */ -+#define __NR_geteuid (__NR_SYSCALL_BASE+ 49) -+#define __NR_getegid (__NR_SYSCALL_BASE+ 50) -+#define __NR_acct (__NR_SYSCALL_BASE+ 51) -+#define __NR_umount2 (__NR_SYSCALL_BASE+ 52) -+ /* 53 was sys_lock */ -+#define __NR_ioctl (__NR_SYSCALL_BASE+ 54) -+#define __NR_fcntl (__NR_SYSCALL_BASE+ 55) -+ /* 56 was sys_mpx */ -+#define __NR_setpgid (__NR_SYSCALL_BASE+ 57) -+ /* 58 was sys_ulimit */ -+ /* 59 was sys_olduname */ -+#define __NR_umask (__NR_SYSCALL_BASE+ 60) -+#define __NR_chroot (__NR_SYSCALL_BASE+ 61) -+#define __NR_ustat (__NR_SYSCALL_BASE+ 62) -+#define __NR_dup2 (__NR_SYSCALL_BASE+ 63) -+#define __NR_getppid (__NR_SYSCALL_BASE+ 64) -+#define __NR_getpgrp (__NR_SYSCALL_BASE+ 65) -+#define __NR_setsid (__NR_SYSCALL_BASE+ 66) -+#define __NR_sigaction (__NR_SYSCALL_BASE+ 67) -+ /* 68 was sys_sgetmask */ -+ /* 69 was sys_ssetmask */ -+#define __NR_setreuid (__NR_SYSCALL_BASE+ 70) -+#define __NR_setregid (__NR_SYSCALL_BASE+ 71) -+#define __NR_sigsuspend (__NR_SYSCALL_BASE+ 72) -+#define __NR_sigpending (__NR_SYSCALL_BASE+ 73) -+#define __NR_sethostname (__NR_SYSCALL_BASE+ 74) -+#define __NR_setrlimit (__NR_SYSCALL_BASE+ 75) -+#define __NR_getrlimit (__NR_SYSCALL_BASE+ 76) /* Back compat 2GB limited rlimit */ -+#define __NR_getrusage (__NR_SYSCALL_BASE+ 77) -+#define __NR_gettimeofday (__NR_SYSCALL_BASE+ 78) -+#define __NR_settimeofday (__NR_SYSCALL_BASE+ 79) -+#define __NR_getgroups (__NR_SYSCALL_BASE+ 80) -+#define __NR_setgroups (__NR_SYSCALL_BASE+ 81) -+#define __NR_select (__NR_SYSCALL_BASE+ 82) -+#define __NR_symlink (__NR_SYSCALL_BASE+ 83) -+ /* 84 was sys_lstat */ -+#define __NR_readlink (__NR_SYSCALL_BASE+ 85) -+#define __NR_uselib (__NR_SYSCALL_BASE+ 86) -+#define __NR_swapon (__NR_SYSCALL_BASE+ 87) -+#define __NR_reboot (__NR_SYSCALL_BASE+ 88) -+#define __NR_readdir (__NR_SYSCALL_BASE+ 89) -+#define __NR_mmap (__NR_SYSCALL_BASE+ 90) -+#define __NR_munmap (__NR_SYSCALL_BASE+ 91) -+#define __NR_truncate (__NR_SYSCALL_BASE+ 92) -+#define __NR_ftruncate (__NR_SYSCALL_BASE+ 93) -+#define __NR_fchmod (__NR_SYSCALL_BASE+ 94) -+#define __NR_fchown (__NR_SYSCALL_BASE+ 95) -+#define __NR_getpriority (__NR_SYSCALL_BASE+ 96) -+#define __NR_setpriority (__NR_SYSCALL_BASE+ 97) -+ /* 98 was sys_profil */ -+#define __NR_statfs (__NR_SYSCALL_BASE+ 99) -+#define __NR_fstatfs (__NR_SYSCALL_BASE+100) -+ /* 101 was sys_ioperm */ -+#define __NR_socketcall (__NR_SYSCALL_BASE+102) -+#define __NR_syslog (__NR_SYSCALL_BASE+103) -+#define __NR_setitimer (__NR_SYSCALL_BASE+104) -+#define __NR_getitimer (__NR_SYSCALL_BASE+105) -+#define __NR_stat (__NR_SYSCALL_BASE+106) -+#define __NR_lstat (__NR_SYSCALL_BASE+107) -+#define __NR_fstat (__NR_SYSCALL_BASE+108) -+ /* 109 was sys_uname */ -+ /* 110 was sys_iopl */ -+#define __NR_vhangup (__NR_SYSCALL_BASE+111) -+ /* 112 was sys_idle */ -+#define __NR_syscall (__NR_SYSCALL_BASE+113) /* syscall to call a syscall! */ -+#define __NR_wait4 (__NR_SYSCALL_BASE+114) -+#define __NR_swapoff (__NR_SYSCALL_BASE+115) -+#define __NR_sysinfo (__NR_SYSCALL_BASE+116) -+#define __NR_ipc (__NR_SYSCALL_BASE+117) -+#define __NR_fsync (__NR_SYSCALL_BASE+118) -+#define __NR_sigreturn (__NR_SYSCALL_BASE+119) -+#define __NR_clone (__NR_SYSCALL_BASE+120) -+#define __NR_setdomainname (__NR_SYSCALL_BASE+121) -+#define __NR_uname (__NR_SYSCALL_BASE+122) -+ /* 123 was sys_modify_ldt */ -+#define __NR_adjtimex (__NR_SYSCALL_BASE+124) -+#define __NR_mprotect (__NR_SYSCALL_BASE+125) -+#define __NR_sigprocmask (__NR_SYSCALL_BASE+126) -+ /* 127 was sys_create_module */ -+#define __NR_init_module (__NR_SYSCALL_BASE+128) -+#define __NR_delete_module (__NR_SYSCALL_BASE+129) -+ /* 130 was sys_get_kernel_syms */ -+#define __NR_quotactl (__NR_SYSCALL_BASE+131) -+#define __NR_getpgid (__NR_SYSCALL_BASE+132) -+#define __NR_fchdir (__NR_SYSCALL_BASE+133) -+#define __NR_bdflush (__NR_SYSCALL_BASE+134) -+#define __NR_sysfs (__NR_SYSCALL_BASE+135) -+#define __NR_personality (__NR_SYSCALL_BASE+136) -+ /* 137 was sys_afs_syscall */ -+#define __NR_setfsuid (__NR_SYSCALL_BASE+138) -+#define __NR_setfsgid (__NR_SYSCALL_BASE+139) -+#define __NR__llseek (__NR_SYSCALL_BASE+140) -+#define __NR_getdents (__NR_SYSCALL_BASE+141) -+#define __NR__newselect (__NR_SYSCALL_BASE+142) -+#define __NR_flock (__NR_SYSCALL_BASE+143) -+#define __NR_msync (__NR_SYSCALL_BASE+144) -+#define __NR_readv (__NR_SYSCALL_BASE+145) -+#define __NR_writev (__NR_SYSCALL_BASE+146) -+#define __NR_getsid (__NR_SYSCALL_BASE+147) -+#define __NR_fdatasync (__NR_SYSCALL_BASE+148) -+#define __NR__sysctl (__NR_SYSCALL_BASE+149) -+#define __NR_mlock (__NR_SYSCALL_BASE+150) -+#define __NR_munlock (__NR_SYSCALL_BASE+151) -+#define __NR_mlockall (__NR_SYSCALL_BASE+152) -+#define __NR_munlockall (__NR_SYSCALL_BASE+153) -+#define __NR_sched_setparam (__NR_SYSCALL_BASE+154) -+#define __NR_sched_getparam (__NR_SYSCALL_BASE+155) -+#define __NR_sched_setscheduler (__NR_SYSCALL_BASE+156) -+#define __NR_sched_getscheduler (__NR_SYSCALL_BASE+157) -+#define __NR_sched_yield (__NR_SYSCALL_BASE+158) -+#define __NR_sched_get_priority_max (__NR_SYSCALL_BASE+159) -+#define __NR_sched_get_priority_min (__NR_SYSCALL_BASE+160) -+#define __NR_sched_rr_get_interval (__NR_SYSCALL_BASE+161) -+#define __NR_nanosleep (__NR_SYSCALL_BASE+162) -+#define __NR_mremap (__NR_SYSCALL_BASE+163) -+#define __NR_setresuid (__NR_SYSCALL_BASE+164) -+#define __NR_getresuid (__NR_SYSCALL_BASE+165) -+#define __NR_getpagesize (__NR_SYSCALL_BASE+166) -+ /* 167 was sys_query_module */ -+#define __NR_poll (__NR_SYSCALL_BASE+168) -+#define __NR_nfsservctl (__NR_SYSCALL_BASE+169) -+#define __NR_setresgid (__NR_SYSCALL_BASE+170) -+#define __NR_getresgid (__NR_SYSCALL_BASE+171) -+#define __NR_prctl (__NR_SYSCALL_BASE+172) -+#define __NR_rt_sigreturn (__NR_SYSCALL_BASE+173) -+#define __NR_rt_sigaction (__NR_SYSCALL_BASE+174) -+#define __NR_rt_sigprocmask (__NR_SYSCALL_BASE+175) -+#define __NR_rt_sigpending (__NR_SYSCALL_BASE+176) -+#define __NR_rt_sigtimedwait (__NR_SYSCALL_BASE+177) -+#define __NR_rt_sigqueueinfo (__NR_SYSCALL_BASE+178) -+#define __NR_rt_sigsuspend (__NR_SYSCALL_BASE+179) -+#define __NR_pread64 (__NR_SYSCALL_BASE+180) -+#define __NR_pwrite64 (__NR_SYSCALL_BASE+181) -+#define __NR_chown (__NR_SYSCALL_BASE+182) -+#define __NR_getcwd (__NR_SYSCALL_BASE+183) -+#define __NR_capget (__NR_SYSCALL_BASE+184) -+#define __NR_capset (__NR_SYSCALL_BASE+185) -+#define __NR_sigaltstack (__NR_SYSCALL_BASE+186) -+#define __NR_sendfile (__NR_SYSCALL_BASE+187) -+ /* 188 reserved */ -+ /* 189 reserved */ -+#define __NR_vfork (__NR_SYSCALL_BASE+190) -+#define __NR_ugetrlimit (__NR_SYSCALL_BASE+191) /* SuS compliant getrlimit */ -+#define __NR_mmap2 (__NR_SYSCALL_BASE+192) -+#define __NR_truncate64 (__NR_SYSCALL_BASE+193) -+#define __NR_ftruncate64 (__NR_SYSCALL_BASE+194) -+#define __NR_stat64 (__NR_SYSCALL_BASE+195) -+#define __NR_lstat64 (__NR_SYSCALL_BASE+196) -+#define __NR_fstat64 (__NR_SYSCALL_BASE+197) -+#define __NR_lchown32 (__NR_SYSCALL_BASE+198) -+#define __NR_getuid32 (__NR_SYSCALL_BASE+199) -+#define __NR_getgid32 (__NR_SYSCALL_BASE+200) -+#define __NR_geteuid32 (__NR_SYSCALL_BASE+201) -+#define __NR_getegid32 (__NR_SYSCALL_BASE+202) -+#define __NR_setreuid32 (__NR_SYSCALL_BASE+203) -+#define __NR_setregid32 (__NR_SYSCALL_BASE+204) -+#define __NR_getgroups32 (__NR_SYSCALL_BASE+205) -+#define __NR_setgroups32 (__NR_SYSCALL_BASE+206) -+#define __NR_fchown32 (__NR_SYSCALL_BASE+207) -+#define __NR_setresuid32 (__NR_SYSCALL_BASE+208) -+#define __NR_getresuid32 (__NR_SYSCALL_BASE+209) -+#define __NR_setresgid32 (__NR_SYSCALL_BASE+210) -+#define __NR_getresgid32 (__NR_SYSCALL_BASE+211) -+#define __NR_chown32 (__NR_SYSCALL_BASE+212) -+#define __NR_setuid32 (__NR_SYSCALL_BASE+213) -+#define __NR_setgid32 (__NR_SYSCALL_BASE+214) -+#define __NR_setfsuid32 (__NR_SYSCALL_BASE+215) -+#define __NR_setfsgid32 (__NR_SYSCALL_BASE+216) -+#define __NR_getdents64 (__NR_SYSCALL_BASE+217) -+#define __NR_pivot_root (__NR_SYSCALL_BASE+218) -+#define __NR_mincore (__NR_SYSCALL_BASE+219) -+#define __NR_madvise (__NR_SYSCALL_BASE+220) -+#define __NR_fcntl64 (__NR_SYSCALL_BASE+221) -+ /* 222 for tux */ -+ /* 223 is unused */ -+#define __NR_gettid (__NR_SYSCALL_BASE+224) -+#define __NR_readahead (__NR_SYSCALL_BASE+225) -+#define __NR_setxattr (__NR_SYSCALL_BASE+226) -+#define __NR_lsetxattr (__NR_SYSCALL_BASE+227) -+#define __NR_fsetxattr (__NR_SYSCALL_BASE+228) -+#define __NR_getxattr (__NR_SYSCALL_BASE+229) -+#define __NR_lgetxattr (__NR_SYSCALL_BASE+230) -+#define __NR_fgetxattr (__NR_SYSCALL_BASE+231) -+#define __NR_listxattr (__NR_SYSCALL_BASE+232) -+#define __NR_llistxattr (__NR_SYSCALL_BASE+233) -+#define __NR_flistxattr (__NR_SYSCALL_BASE+234) -+#define __NR_removexattr (__NR_SYSCALL_BASE+235) -+#define __NR_lremovexattr (__NR_SYSCALL_BASE+236) -+#define __NR_fremovexattr (__NR_SYSCALL_BASE+237) -+#define __NR_tkill (__NR_SYSCALL_BASE+238) -+#define __NR_sendfile64 (__NR_SYSCALL_BASE+239) -+#define __NR_futex (__NR_SYSCALL_BASE+240) -+#define __NR_sched_setaffinity (__NR_SYSCALL_BASE+241) -+#define __NR_sched_getaffinity (__NR_SYSCALL_BASE+242) -+#define __NR_io_setup (__NR_SYSCALL_BASE+243) -+#define __NR_io_destroy (__NR_SYSCALL_BASE+244) -+#define __NR_io_getevents (__NR_SYSCALL_BASE+245) -+#define __NR_io_submit (__NR_SYSCALL_BASE+246) -+#define __NR_io_cancel (__NR_SYSCALL_BASE+247) -+#define __NR_exit_group (__NR_SYSCALL_BASE+248) -+#define __NR_lookup_dcookie (__NR_SYSCALL_BASE+249) -+#define __NR_epoll_create (__NR_SYSCALL_BASE+250) -+#define __NR_epoll_ctl (__NR_SYSCALL_BASE+251) -+#define __NR_epoll_wait (__NR_SYSCALL_BASE+252) -+#define __NR_remap_file_pages (__NR_SYSCALL_BASE+253) -+ /* 254 for set_thread_area */ -+ /* 255 for get_thread_area */ -+#define __NR_set_tid_address (__NR_SYSCALL_BASE+256) -+#define __NR_timer_create (__NR_SYSCALL_BASE+257) -+#define __NR_timer_settime (__NR_SYSCALL_BASE+258) -+#define __NR_timer_gettime (__NR_SYSCALL_BASE+259) -+#define __NR_timer_getoverrun (__NR_SYSCALL_BASE+260) -+#define __NR_timer_delete (__NR_SYSCALL_BASE+261) -+#define __NR_clock_settime (__NR_SYSCALL_BASE+262) -+#define __NR_clock_gettime (__NR_SYSCALL_BASE+263) -+#define __NR_clock_getres (__NR_SYSCALL_BASE+264) -+#define __NR_clock_nanosleep (__NR_SYSCALL_BASE+265) -+#define __NR_statfs64 (__NR_SYSCALL_BASE+266) -+#define __NR_fstatfs64 (__NR_SYSCALL_BASE+267) -+#define __NR_tgkill (__NR_SYSCALL_BASE+268) -+#define __NR_utimes (__NR_SYSCALL_BASE+269) -+#define __NR_fadvise64_64 (__NR_SYSCALL_BASE+270) -+#define __NR_pciconfig_iobase (__NR_SYSCALL_BASE+271) -+#define __NR_pciconfig_read (__NR_SYSCALL_BASE+272) -+#define __NR_pciconfig_write (__NR_SYSCALL_BASE+273) -+#define __NR_mq_open (__NR_SYSCALL_BASE+274) -+#define __NR_mq_unlink (__NR_SYSCALL_BASE+275) -+#define __NR_mq_timedsend (__NR_SYSCALL_BASE+276) -+#define __NR_mq_timedreceive (__NR_SYSCALL_BASE+277) -+#define __NR_mq_notify (__NR_SYSCALL_BASE+278) -+#define __NR_mq_getsetattr (__NR_SYSCALL_BASE+279) -+#define __NR_waitid (__NR_SYSCALL_BASE+280) -+#define __NR_add_key (__NR_SYSCALL_BASE+281) -+#define __NR_request_key (__NR_SYSCALL_BASE+282) -+#define __NR_keyctl (__NR_SYSCALL_BASE+283) -+#define __NR_ioprio_set (__NR_SYSCALL_BASE+284) -+#define __NR_ioprio_get (__NR_SYSCALL_BASE+285) -+#define __NR_inotify_init (__NR_SYSCALL_BASE+286) -+#define __NR_inotify_add_watch (__NR_SYSCALL_BASE+287) -+#define __NR_inotify_rm_watch (__NR_SYSCALL_BASE+288) -+#define __NR_migrate_pages (__NR_SYSCALL_BASE+289) -+#define __NR_openat (__NR_SYSCALL_BASE+290) -+#define __NR_mkdirat (__NR_SYSCALL_BASE+291) -+#define __NR_mknodat (__NR_SYSCALL_BASE+292) -+#define __NR_fchownat (__NR_SYSCALL_BASE+293) -+#define __NR_futimesat (__NR_SYSCALL_BASE+294) -+#define __NR_fstatat64 (__NR_SYSCALL_BASE+295) -+#define __NR_unlinkat (__NR_SYSCALL_BASE+296) -+#define __NR_renameat (__NR_SYSCALL_BASE+297) -+#define __NR_linkat (__NR_SYSCALL_BASE+298) -+#define __NR_symlinkat (__NR_SYSCALL_BASE+299) -+#define __NR_readlinkat (__NR_SYSCALL_BASE+300) -+#define __NR_fchmodat (__NR_SYSCALL_BASE+301) -+#define __NR_faccessat (__NR_SYSCALL_BASE+302) -+#define __NR_pselect6 (__NR_SYSCALL_BASE+303) -+#define __NR_ppoll (__NR_SYSCALL_BASE+304) -+#define __NR_unshare (__NR_SYSCALL_BASE+305) -+#define __NR_set_robust_list (__NR_SYSCALL_BASE+306) -+#define __NR_get_robust_list (__NR_SYSCALL_BASE+307) -+#define __NR_splice (__NR_SYSCALL_BASE+308) -+#define __NR_sync_file_range2 (__NR_SYSCALL_BASE+309) -+#define __NR_tee (__NR_SYSCALL_BASE+310) -+#define __NR_vmsplice (__NR_SYSCALL_BASE+311) -+#define __NR_move_pages (__NR_SYSCALL_BASE+312) -+#define __NR_fadvise64 (__NR_SYSCALL_BASE+313) -+#define __NR_utimensat (__NR_SYSCALL_BASE+314) -+#define __NR_signalfd (__NR_SYSCALL_BASE+315) -+#define __NR_timerfd_create (__NR_SYSCALL_BASE+316) -+#define __NR_eventfd (__NR_SYSCALL_BASE+317) -+#define __NR_fallocate (__NR_SYSCALL_BASE+318) -+#define __NR_timerfd_settime (__NR_SYSCALL_BASE+319) -+#define __NR_timerfd_gettime (__NR_SYSCALL_BASE+320) -+#define __NR_getcpu (__NR_SYSCALL_BASE+321) -+#define __NR_signalfd4 (__NR_SYSCALL_BASE+322) -+#define __NR_eventfd2 (__NR_SYSCALL_BASE+323) -+#define __NR_epoll_create1 (__NR_SYSCALL_BASE+324) -+#define __NR_dup3 (__NR_SYSCALL_BASE+325) -+#define __NR_pipe2 (__NR_SYSCALL_BASE+326) -+#define __NR_inotify_init1 (__NR_SYSCALL_BASE+327) -+#define __NR_kexec_load (__NR_SYSCALL_BASE+328) -+#define __NR_accept (__NR_SYSCALL_BASE+329) -+#define __NR_bind (__NR_SYSCALL_BASE+330) -+#define __NR_connect (__NR_SYSCALL_BASE+331) -+#define __NR_getpeername (__NR_SYSCALL_BASE+332) -+#define __NR_getsockname (__NR_SYSCALL_BASE+333) -+#define __NR_getsockopt (__NR_SYSCALL_BASE+334) -+#define __NR_listen (__NR_SYSCALL_BASE+335) -+#define __NR_recv (__NR_SYSCALL_BASE+336) -+#define __NR_recvfrom (__NR_SYSCALL_BASE+337) -+#define __NR_recvmsg (__NR_SYSCALL_BASE+338) -+#define __NR_send (__NR_SYSCALL_BASE+339) -+#define __NR_sendmsg (__NR_SYSCALL_BASE+340) -+#define __NR_sendto (__NR_SYSCALL_BASE+341) -+#define __NR_setsockopt (__NR_SYSCALL_BASE+342) -+#define __NR_shutdown (__NR_SYSCALL_BASE+343) -+#define __NR_socket (__NR_SYSCALL_BASE+344) -+#define __NR_socketpair (__NR_SYSCALL_BASE+345) -+#define __NR_prlimit64 (__NR_SYSCALL_BASE+346) -+#define __NR_accept4 (__NR_SYSCALL_BASE+347) -+#define __NR_recvmmsg (__NR_SYSCALL_BASE+348) -+#define __NR_sendmmsg (__NR_SYSCALL_BASE+349) -+#define __NR_fanotify_init (__NR_SYSCALL_BASE+350) -+#define __NR_fanotify_mark (__NR_SYSCALL_BASE+351) -+#define __NR_msgget (__NR_SYSCALL_BASE+352) -+#define __NR_msgctl (__NR_SYSCALL_BASE+353) -+#define __NR_msgrcv (__NR_SYSCALL_BASE+354) -+#define __NR_msgsnd (__NR_SYSCALL_BASE+355) -+#define __NR_semget (__NR_SYSCALL_BASE+356) -+#define __NR_semctl (__NR_SYSCALL_BASE+357) -+#define __NR_semtimedop (__NR_SYSCALL_BASE+358) -+#define __NR_semop (__NR_SYSCALL_BASE+359) -+#define __NR_shmget (__NR_SYSCALL_BASE+360) -+#define __NR_shmctl (__NR_SYSCALL_BASE+361) -+#define __NR_shmat (__NR_SYSCALL_BASE+362) -+#define __NR_shmdt (__NR_SYSCALL_BASE+363) -+#define __NR_syncfs (__NR_SYSCALL_BASE+364) -+#define __NR_setns (__NR_SYSCALL_BASE+365) -+#define __NR_name_to_handle_at (__NR_SYSCALL_BASE+366) -+#define __NR_open_by_handle_at (__NR_SYSCALL_BASE+367) -+#define __NR_process_vm_readv (__NR_SYSCALL_BASE+368) -+#define __NR_process_vm_writev (__NR_SYSCALL_BASE+369) -+#define __NR_clock_adjtime (__NR_SYSCALL_BASE+370) -+#define __NR_get_mempolicy (__NR_SYSCALL_BASE+371) -+#define __NR_mbind (__NR_SYSCALL_BASE+372) -+#define __NR_perf_event_open (__NR_SYSCALL_BASE+373) -+#define __NR_preadv (__NR_SYSCALL_BASE+374) -+#define __NR_pwritev (__NR_SYSCALL_BASE+375) -+#define __NR_rt_tgsigqueueinfo (__NR_SYSCALL_BASE+376) -+#define __NR_set_mempolicy (__NR_SYSCALL_BASE+377) -+#define __NR_epoll_pwait (__NR_SYSCALL_BASE+378) -+ -+ -+ -+ -+#define __NR_lmmap (__NR_NDS32_BASE+ 1) -+#define __NR_lmunmap (__NR_NDS32_BASE+ 2) -+#define __NR_lmdma (__NR_NDS32_BASE+ 3) -+#define __NR_pfmctl (__NR_NDS32_BASE+ 4) -+#define __NR_getpfm (__NR_NDS32_BASE+ 5) -+#define __NR_setpfm (__NR_NDS32_BASE+ 6) -+#define __NR_wbna (__NR_NDS32_BASE+ 7) -+ -+ -+ -+#ifdef __KERNEL__ -+ -+#define __ARCH_WANT_IPC_PARSE_VERSION -+#define __ARCH_WANT_OLD_READDIR -+#define __ARCH_WANT_STAT64 -+#define __ARCH_WANT_SYS_ALARM -+#define __ARCH_WANT_SYS_GETHOSTNAME -+#define __ARCH_WANT_SYS_PAUSE -+#define __ARCH_WANT_SYS_TIME -+#define __ARCH_WANT_SYS_UTIME -+#define __ARCH_WANT_SYS_SOCKETCALL -+#define __ARCH_WANT_SYS_FADVISE64 -+#define __ARCH_WANT_SYS_GETPGRP -+#define __ARCH_WANT_SYS_LLSEEK -+#define __ARCH_WANT_SYS_NICE -+#define __ARCH_WANT_SYS_OLD_GETRLIMIT -+#define __ARCH_WANT_SYS_OLD_MMAP -+#define __ARCH_WANT_SYS_OLDUMOUNT -+#define __ARCH_WANT_SYS_SIGPENDING -+#define __ARCH_WANT_SYS_SIGPROCMASK -+#define __ARCH_WANT_SYS_RT_SIGACTION -+ -+/* -+ * "Conditional" syscalls -+ * -+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), -+ * but it doesn't work on all toolchains, so we just do it by hand -+ */ -+#define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall"); -+ -+#endif -+#endif /* __ASM_NDS32_UNISTD_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/user.h linux-3.4.113/arch/nds32/include/asm/user.h ---- linux-3.4.113.orig/arch/nds32/include/asm/user.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/user.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,89 @@ -+/* -+ * linux/arch/nds32/include/asm/user.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef _NDS32_USER_H -+#define _NDS32_USER_H -+ -+#include -+#include -+/* Core file format: The core file is written in such a way that gdb -+ can understand it and provide useful information to the user (under -+ linux we use the 'trad-core' bfd). There are quite a number of -+ obstacles to being able to view the contents of the floating point -+ registers, and until these are solved you will not be able to view the -+ contents of them. Actually, you can read in the core file and look at -+ the contents of the user struct to find out what the floating point -+ registers contain. -+ The actual file contents are as follows: -+ UPAGE: 1 page consisting of a user struct that tells gdb what is present -+ in the file. Directly after this is a copy of the task_struct, which -+ is currently not used by gdb, but it may come in useful at some point. -+ All of the registers are stored as part of the upage. The upage should -+ always be only one page. -+ DATA: The data area is stored. We use current->end_text to -+ current->brk to pick up all of the user variables, plus any memory -+ that may have been malloced. No attempt is made to determine if a page -+ is demand-zero or if a page is totally unused, we just cover the entire -+ range. All of the addresses are rounded in such a way that an integral -+ number of pages is written. -+ STACK: We need the stack information in order to get a meaningful -+ backtrace. We need to write the data from (esp) to -+ current->start_stack, so we round each of these off in order to be able -+ to write an integer number of pages. -+ The minimum core file size is 3 pages, or 12288 bytes. -+*/ -+ -+struct user_fp { -+ struct fp_reg { -+ unsigned int sign1:1; -+ unsigned int unused:15; -+ unsigned int sign2:1; -+ unsigned int exponent:14; -+ unsigned int j:1; -+ unsigned int mantissa1:31; -+ unsigned int mantissa0:32; -+ } fpregs[8]; -+ unsigned int fpsr:32; -+ unsigned int fpcr:32; -+ unsigned char ftype[8]; -+ unsigned int init_flag; -+}; -+ -+/* When the kernel dumps core, it starts by dumping the user struct - -+ this will be used by gdb to figure out where the data and stack segments -+ are within the file, and what virtual addresses to use. */ -+struct user{ -+/* We start with the registers, to mimic the way that "memory" is returned -+ from the ptrace(3,...) function. */ -+ struct pt_regs regs; /* Where the registers are actually stored */ -+/* ptrace does not yet supply these. Someday.... */ -+ int u_fpvalid; /* True if math co-processor being used. */ -+ /* for this mess. Not yet used. */ -+/* The rest of this junk is to help gdb figure out what goes where */ -+ unsigned long int u_tsize; /* Text segment size (pages). */ -+ unsigned long int u_dsize; /* Data segment size (pages). */ -+ unsigned long int u_ssize; /* Stack segment size (pages). */ -+ unsigned long start_code; /* Starting virtual address of text. */ -+ unsigned long start_stack; /* Starting virtual address of stack area. -+ This is actually the bottom of the stack, -+ the top of the stack is always found in the -+ esp register. */ -+ long int signal; /* Signal that caused the core dump. */ -+ int reserved; /* No longer used */ -+ struct pt_regs * u_ar0; /* Used by gdb to help find the values for */ -+ /* the registers. */ -+ unsigned long magic; /* To uniquely identify a core file */ -+ char u_comm[32]; /* User command that was responsible */ -+ int u_debugreg[8]; -+ struct user_fp u_fp; /* FP state */ -+ struct user_fp_struct * u_fp0;/* Used by gdb to help find the values for */ -+ /* the FP registers. */ -+}; -+#define NBPG PAGE_SIZE -+#define UPAGES 1 -+#define HOST_TEXT_START_ADDR (u.start_code) -+#define HOST_STACK_END_ADDR (u.start_stack + u.u_ssize * NBPG) -+ -+#endif /* _NDS32_USER_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/vga.h linux-3.4.113/arch/nds32/include/asm/vga.h ---- linux-3.4.113.orig/arch/nds32/include/asm/vga.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/vga.h 2016-12-01 20:59:24.348612597 +0100 -@@ -0,0 +1,17 @@ -+/* -+ * linux/arch/nds32/include/asm/vga.h -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#ifndef ASMNDS32_VGA_H -+#define ASMNDS32_VGA_H -+ -+#include -+#include -+ -+#define VGA_MAP_MEM(x) (PCIMEM_BASE + (x)) -+ -+#define vga_readb(x) (*((volatile unsigned char *)x)) -+#define vga_writeb(x,y) (*((volatile unsigned char *)y) = (x)) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/vmalloc.h linux-3.4.113/arch/nds32/include/asm/vmalloc.h ---- linux-3.4.113.orig/arch/nds32/include/asm/vmalloc.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/vmalloc.h 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,31 @@ -+/* -+ * linux/arch/nds32/include/asm/vmalloc.h -+ * -+ * Faraday Platform Independent Virtual Memory Configuration -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/16/2005 Copy from Faraday CPE codes. -+ */ -+ -+#ifndef __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ -+#define __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ -+ -+#endif /* __FARADAY_PLATFORM_INDEPENDENT_VMALLOC_HEADER__ */ -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/xor.h linux-3.4.113/arch/nds32/include/asm/xor.h ---- linux-3.4.113.orig/arch/nds32/include/asm/xor.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/xor.h 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,157 @@ -+/* -+ * linux/arch/nds32/include/asm/xor.h -+ * -+ * Copyright (C) 2001 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+ -+#define __XOR(a1, a2) a1 ^= a2 -+ -+ -+#define GET_BLOCK_2(dst) \ -+ __asm__( \ -+ " lmw.bim %1, [%0], %2 \n"\ -+ : "=r" (dst), "=r" (a1), "=r" (a2) \ -+ : "0" (dst)) -+ -+#define GET_BLOCK_4(dst) \ -+ __asm__( \ -+ " lmw.bim %1, [%0], %1 \n" \ //ldmia %0, {%1, %2, %3, %4} -+ " lmw.bim %2, [%0], %2 \n" \ -+ " lmw.bim %3, [%0], %3 \n" \ -+ " lmw.bim %4, [%0], %4 \n" \ -+ : "=r" (dst), "=r" (a1), "=r" (a2), "=r" (a3), "=r" (a4) \ -+ : "0" (dst)) -+ -+#define XOR_BLOCK_2(src) \ -+ __asm__(\ -+ " lmw.bim %1, [%0], %2 \n " \ -+ " lmw.bim %2, [%0], %2 \n" \ -+ : "=r" (src), "=r" (b1), "=r" (b2) \ -+ : "0" (src)); \ -+ __XOR(a1, b1); __XOR(a2, b2); -+ -+ -+#define XOR_BLOCK_4(src) \ -+ __asm__(\ -+ "lmw.bim %1, [%0], %1 \n " \ // ldmia %0!, {%1, %2, %3, %4} -+ "lmw.bim %2, [%0], %2 \n " \ -+ "lmw.bim %3, [%0], %3 \n " \ -+ "lmw.bim %4, [%0], %4 \n " \ -+ : "=r" (src), "=r" (b1), "=r" (b2), "=r" (b3), "=r" (b4) \ -+ : "0" (src)); \ -+ __XOR(a1, b1); __XOR(a2, b2); __XOR(a3, b3); __XOR(a4, b4) -+ -+#define PUT_BLOCK_2(dst) \ -+ __asm__ __volatile__( \ -+ " smw.bim %2, [%0], %3" \ -+ : "=r" (dst) \ -+ : "0" (dst), "r" (a1), "r" (a2)) -+ -+#define PUT_BLOCK_4(dst) \ -+ __asm__ __volatile__( \ -+ " smw.bim %2, [%0], %5 \n" \ -+ : "=r" (dst) \ -+ : "0" (dst), "r" (a1), "r" (a2), "r" (a3), "r" (a4)) -+ -+static void -+xor_nds32regs_2(unsigned long bytes, unsigned long *p1, unsigned long *p2) -+{ -+ unsigned int lines = bytes / sizeof(unsigned long) / 4; -+ register unsigned int a1 __asm__("r4"); -+ register unsigned int a2 __asm__("r5"); -+ register unsigned int a3 __asm__("r6"); -+ register unsigned int a4 __asm__("r7"); -+ register unsigned int b1 __asm__("r8"); -+ register unsigned int b2 __asm__("r9"); -+ register unsigned int b3 __asm__("p0"); -+ register unsigned int b4 __asm__("ra"); -+ -+ do { -+ GET_BLOCK_4(p1); -+ XOR_BLOCK_4(p2); -+ PUT_BLOCK_4(p1); -+ } while (--lines); -+} -+ -+static void -+xor_nds32regs_3(unsigned long bytes, unsigned long *p1, unsigned long *p2, -+ unsigned long *p3) -+{ -+ unsigned int lines = bytes / sizeof(unsigned long) / 4; -+ register unsigned int a1 __asm__("r4"); -+ register unsigned int a2 __asm__("r5"); -+ register unsigned int a3 __asm__("r6"); -+ register unsigned int a4 __asm__("r7"); -+ register unsigned int b1 __asm__("r8"); -+ register unsigned int b2 __asm__("r9"); -+ register unsigned int b3 __asm__("p0"); -+ register unsigned int b4 __asm__("ra"); -+ -+ do { -+ GET_BLOCK_4(p1); -+ XOR_BLOCK_4(p2); -+ XOR_BLOCK_4(p3); -+ PUT_BLOCK_4(p1); -+ } while (--lines); -+} -+ -+static void -+xor_nds32regs_4(unsigned long bytes, unsigned long *p1, unsigned long *p2, -+ unsigned long *p3, unsigned long *p4) -+{ -+ unsigned int lines = bytes / sizeof(unsigned long) / 2; -+ register unsigned int a1 __asm__("r8"); -+ register unsigned int a2 __asm__("r9"); -+ register unsigned int b1 __asm__("p0"); -+ register unsigned int b2 __asm__("ra"); -+ -+ do { -+ GET_BLOCK_2(p1); -+ XOR_BLOCK_2(p2); -+ XOR_BLOCK_2(p3); -+ XOR_BLOCK_2(p4); -+ PUT_BLOCK_2(p1); -+ } while (--lines); -+} -+ -+static void -+xor_nds32regs_5(unsigned long bytes, unsigned long *p1, unsigned long *p2, -+ unsigned long *p3, unsigned long *p4, unsigned long *p5) -+{ -+ unsigned int lines = bytes / sizeof(unsigned long) / 2; -+ register unsigned int a1 __asm__("r8"); -+ register unsigned int a2 __asm__("r9"); -+ register unsigned int b1 __asm__("p0"); -+ register unsigned int b2 __asm__("ra"); -+ -+ do { -+ GET_BLOCK_2(p1); -+ XOR_BLOCK_2(p2); -+ XOR_BLOCK_2(p3); -+ XOR_BLOCK_2(p4); -+ XOR_BLOCK_2(p5); -+ PUT_BLOCK_2(p1); -+ } while (--lines); -+} -+ -+static struct xor_block_template xor_block_nds32regs = { -+ .name = "nds32regs", -+ .do_2 = xor_nds32regs_2, -+ .do_3 = xor_nds32regs_3, -+ .do_4 = xor_nds32regs_4, -+ .do_5 = xor_nds32regs_5, -+}; -+ -+#undef XOR_TRY_TEMPLATES -+#define XOR_TRY_TEMPLATES \ -+ do { \ -+ xor_speed(&xor_block_nds32regs); \ -+ xor_speed(&xor_block_8regs); \ -+ xor_speed(&xor_block_32regs); \ -+ } while (0) -diff -Nur linux-3.4.113.orig/arch/nds32/Kconfig linux-3.4.113/arch/nds32/Kconfig ---- linux-3.4.113.orig/arch/nds32/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/Kconfig 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,249 @@ -+# -+# For a description of the syntax of this configuration file, -+# see Documentation/kbuild/kconfig-language.txt. -+# -+ -+config NDS32 -+ bool -+ default y -+ select RTC_LIB -+ select HAVE_OPROFILE -+ select HAVE_ARCH_KGDB -+ select HAVE_KPROBES -+ select HAVE_KRETPROBES -+ select HAVE_FUNCTION_TRACER -+ select HAVE_FUNCTION_GRAPH_TRACER -+ select HAVE_FUNCTION_TRACE_MCOUNT_TEST -+ select SYS_SUPPORTS_APM_EMULATION -+ select HAVE_IDE -+ select HAVE_MEMBLOCK -+ select HAVE_MEMBLOCK_NODE_MAP -+ -+config GENERIC_GPIO -+ bool -+ default n -+ -+config GENERIC_TIME -+ bool -+ default y -+ -+config GENERIC_CLOCKEVENTS -+ bool -+ default y -+ -+config NO_IOPORT -+ bool -+ default y -+ -+config GENERIC_IOMAP -+ def_bool y -+ -+config GENERIC_LOCKBREAK -+ bool -+ default y -+ depends on SMP && PREEMPT -+ -+config RWSEM_GENERIC_SPINLOCK -+ bool -+ default y -+ -+config RWSEM_XCHGADD_ALGORITHM -+ bool -+ -+config GENERIC_HWEIGHT -+ bool -+ default y -+ -+config GENERIC_FIND_NEXT_BIT -+ bool -+ default y -+ -+config GENERIC_CALIBRATE_DELAY -+ bool -+ default y -+ -+config GENERIC_BUST_SPINLOCK -+ bool -+ -+config GENERIC_HARDIRQS -+ bool -+ default y -+ -+config GENERIC_HARDIRQS_NO__DO_IRQ -+ def_bool y -+ -+config LOCKDEP_SUPPORT -+ bool -+ default y -+ -+config STACKTRACE_SUPPORT -+ bool -+ default y -+ -+config HAVE_LATENCYTOP_SUPPORT -+ def_bool y -+ -+source "init/Kconfig" -+source "kernel/Kconfig.freezer" -+ -+menu "System Type" -+source "arch/nds32/platforms/Kconfig" -+source "arch/nds32/Kconfig.cpu" -+ -+config VECTORS_BASE -+ hex -+ default 0xfeff0000 if MMU || CPU_HIGH_VECTOR -+ default DRAM_BASE if REMAP_VECTORS_TO_RAM -+ default 0x00000000 -+ help -+ The base address of exception vectors. -+ -+config MMU -+ bool -+ default y -+ -+endmenu -+ -+menu "Kernel Features" -+source "kernel/time/Kconfig" -+ -+config SMP -+ bool "Symmetric Multi-Processing" -+ depends on PLATFORM_AMIC -+ select USE_GENERIC_SMP_HELPERS -+ help -+ This enables support for systems with more than one CPU. If you have -+ a system with only one CPU, like most personal computers, say N. If -+ you have a system with more than one CPU, say Y. -+ -+ If you say N here, the kernel will run on single and multiprocessor -+ machines, but will use only one CPU of a multiprocessor machine. If -+ you say Y here, the kernel will run on many, but not all, single -+ processor machines. On a single processor machine, the kernel will -+ run faster if you say N here. -+ -+ See also the , -+ , , -+ and the SMP-HOWTO available at -+ . -+ -+ If you don't know what to do here, say N. -+ -+config NR_CPUS -+ int "Maximum number of CPUs (2-32)" -+ depends on SMP -+ default "4" -+ -+source "kernel/Kconfig.preempt" -+source "mm/Kconfig" -+ -+config FORCE_MAX_ZONEORDER -+ int "MAX_ORDER for the Page Allocator" -+ default "11" -+ -+source "kernel/Kconfig.hz" -+ -+config CMDLINE -+ string "Default kernel command string" -+ default "mem=64M@0x0 initrd=0x800000,8M root=/dev/ram0 rw console=ttyS0,38400n8 rootfstype=ext2 init=/sbin/init -s" -+ -+endmenu -+ -+menu "Power management options" -+ -+config SYS_SUPPORTS_APM_EMULATION -+ bool -+ -+config ARCH_SUSPEND_POSSIBLE -+ def_bool y -+ -+source "kernel/power/Kconfig" -+ -+if PLAT_AG101 || PLAT_AG102 -+source "drivers/cpufreq/Kconfig" -+ -+if PLAT_AG101 -+choice -+ prompt "Default CPUFreq Implementation" -+ depends on CPU_FREQ -+ default AG101_CPU_FREQ_SCALING_MODE -+ help -+ This option sets which CPUFreq governor shall be loaded at -+ startup. If in doubt, select 'performance'. -+config AG101_CPU_FREQ_SCALING_MODE -+ bool "AG101 Frequency Scaling Mode" -+ help -+ Rescale CPU frequency and Bus clock without changing PLL. -+ -+config AG101_CPU_FREQ_FCS -+ bool "AG101 Frequency Change Sequence (FCS)" -+ help -+ The Frequency Change Sequence (FCS) is used to change the system -+ clock frequency. While in the FCS, the system clocks stop. This -+ mode is intended for setting a different frequency to overwrite -+ the default value at initial boot-up. This can be used as a powr- -+ saving feature that allows the AG101 to run at the minimum required -+ frequency -+endchoice -+endif -+ -+if PLAT_AG102 -+choice -+ prompt "Default CPUFreq Implementation" -+ depends on CPU_FREQ -+ default AG102_CPU_FREQ_SCALING_MODE -+ help -+ This option sets which CPUFreq governor shall be loaded at -+ startup. If in doubt, select 'performance'. -+config AG102_CPU_FREQ_SCALING_MODE -+ bool "AG102 Frequency Scaling Mode" -+ help -+ Rescale CPU frequency and Bus clock without changing PLL. -+ -+config AG102_CPU_FREQ_FCS -+ bool "AG102 Frequency Change Sequence (FCS)" -+ help -+ The Frequency Change Sequence (FCS) is used to change the system -+ clock frequency. While in the FCS, the system clocks stop. This -+ mode is intended for setting a different frequency to overwrite -+ the default value at initial boot-up. This can be used as a powr- -+ saving feature that allows the AG101 to run at the minimum required -+ frequency -+endchoice -+endif -+ -+ -+endif -+ -+endmenu -+ -+menu "Bus options" -+ -+config PCI -+ bool "PCI support" -+ help -+ Find out whether you have a PCI motherboard. PCI is the name of a -+ bus system, i.e. the way the CPU talks to the other stuff inside -+ your box. Other bus systems are ISA, EISA, MicroChannel (MCA) or -+ VESA. If you have PCI, say Y, otherwise N. -+ -+ The PCI-HOWTO, available from -+ , contains valuable -+ information about which PCI hardware does work under Linux and which -+ doesn't. -+ -+source "drivers/pci/Kconfig" -+ -+endmenu -+ -+menu "Executable file formats" -+source "fs/Kconfig.binfmt" -+endmenu -+ -+source "net/Kconfig" -+source "drivers/Kconfig" -+source "fs/Kconfig" -+source "arch/nds32/Kconfig.debug" -+source "security/Kconfig" -+source "crypto/Kconfig" -+source "lib/Kconfig" -diff -Nur linux-3.4.113.orig/arch/nds32/Kconfig.cpu linux-3.4.113/arch/nds32/Kconfig.cpu ---- linux-3.4.113.orig/arch/nds32/Kconfig.cpu 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/Kconfig.cpu 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,148 @@ -+comment "Processor Features" -+config CPU_N1213 -+ bool -+ -+config CPU_N1213_43U1HA0 -+ bool -+ -+config CPU_N1233F -+ bool -+ -+config CPU_CUSTOM -+ bool -+ -+config FPU -+ bool "fpu support" -+ -+config UNLAZY_FPU -+ bool "Unlazy FPU support" -+ depends on FPU -+ help -+ Say Y here to enable unlazy FPU and disable lazy FPU. -+ -+ -+config AUDIO -+ bool "audio support" if CPU_CUSTOM -+ -+config HWZOL -+ bool "hardware zero overhead loop support" -+ default y -+ -+config UNLAZY_AUDIO -+ bool "Unlazy audio support" -+ depends on AUDIO -+ help -+ Say Y here to enable unlazy audio and disable lazy audio. -+choice -+ prompt "Vector Interrupt Controller mode" -+ default IVIC_INTC -+config IVIC_INTC -+ bool "IVIC mode with Interrupt Controller" -+config IVIC -+ bool "IVIC mode" -+config EVIC -+ bool "EVIC mode" -+endchoice -+ -+config CPU_NO_CONTEXT_ID -+ def_bool CPU_N1213_43U1HA0 || SMP -+ -+config CPU_CACHE_NONALIASING -+ bool "Non-aliasing cache" -+ -+choice -+ prompt "Paging -- page size " -+ default ANDES_PAGE_SIZE_4KB -+config ANDES_PAGE_SIZE_4KB -+ bool "use 4KB page size" -+config ANDES_PAGE_SIZE_8KB -+ bool "use 8KB page size" -+endchoice -+ -+config NO_KERNEL_LARGE_PAGE -+ def_bool CPU_N1213_43U1HA0 || SMP -+ -+config CPU_ICACHE_DISABLE -+ bool "Disable I-Cache" -+ help -+ Say Y here to disable the processor instruction cache. Unless -+ you have a reason not to or are unsure, say N. -+ -+config CPU_DCACHE_DISABLE -+ bool "Disable D-Cache" -+ help -+ Say Y here to disable the processor data cache. Unless -+ you have a reason not to or are unsure, say N. -+ -+config CPU_DCACHE_WRITETHROUGH -+ bool "Force write through D-cache" -+ depends on !CPU_DCACHE_DISABLE -+ help -+ Say Y here to use the data cache in writethrough mode. Unless you -+ specifically require this or are unsure, say N. -+ -+config KEXEC -+ bool "Kexec system call (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ help -+ kexec is a system call that implements the ability to shutdown your -+ current kernel, and to start another kernel. It is like a reboot -+ but it is independent of the system firmware. And like a reboot -+ you can start any kernel with it, not just Linux. -+ -+ It is an ongoing process to be certain the hardware in a machine -+ is properly shutdown, so do not be surprised if this code does not -+ initially work for you. It may help to enable device hotplugging -+ support. -+ -+config ABI1 -+ bool "Allow ABI 1 binaries to run with this kernel (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ default n -+ help -+ This option preserves the old syscall interface of ABI 1. If -+ you know you'll be using ABI 2 or 2fp then you can say N here. -+ If this option is not selected and you attempt to execute a -+ legacy ABI binary then the result will be UNPREDICTABLE -+ (in fact it can be predicted that it won't work at all). If -+ in doubt say Y. -+ -+config WBNA -+ bool "WBNA" -+ default n -+ help -+ Say Y here to enable write-back memory with no-write-allocation policy. -+ -+config HSS -+ bool "Using Hardware Single-Step (HSS) instead of software breakpoint" -+ default y -+ -+config ALIGNMENT_TRAP -+ tristate "Kernel support unaligned access handling" -+ depends on EXPERIMENTAL -+ default y -+ help -+ Andes processors cannot fetch/store information which is not -+ naturally aligned on the bus, i.e., a 4 byte fetch must start at an -+ address divisible by 4. On 32-bit Andes processors, these non-aligned -+ fetch/store instructions will be emulated in software if you say -+ here, which has a severe performance impact. This is necessary for -+ correct operation of some network protocols. With an IP-only -+ configuration it is safe to say N, otherwise say Y. -+ -+config HIGHMEM -+ bool "High Memory Support" -+ depends on MMU -+ help -+ The address space of ARM processors is only 4 Gigabytes large -+ and it has to accommodate user address space, kernel address -+ space as well as some memory mapped IO. That means that, if you -+ have a large amount of physical memory and/or IO, not all of the -+ memory can be "permanently mapped" by the kernel. The physical -+ memory that is not permanently mapped is called "high memory". -+ -+ Depending on the selected kernel/user memory split, minimum -+ vmalloc space and actual amount of RAM, you may not need this -+ option which should result in a slightly faster kernel. -+ -+ If unsure, say n. -diff -Nur linux-3.4.113.orig/arch/nds32/Kconfig.debug linux-3.4.113/arch/nds32/Kconfig.debug ---- linux-3.4.113.orig/arch/nds32/Kconfig.debug 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/Kconfig.debug 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,82 @@ -+menu "Kernel hacking" -+ -+config TRACE_IRQFLAGS_SUPPORT -+ bool -+ default y -+ -+source "lib/Kconfig.debug" -+ -+config FRAME_POINTER -+ bool -+ default y -+ help -+ If you say N here, the resulting kernel will be slightly smaller and -+ faster. However, when a problem occurs with the kernel, the -+ information that is reported is severely limited. Most people -+ should say Y here. -+ -+config DEBUG_USER -+ bool "Verbose user fault messages" -+ help -+ When a user program crashes due to an exception, the kernel can -+ print a brief message explaining what the problem was. This is -+ sometimes helpful for debugging but serves no purpose on a -+ production system. Most people should say N here. -+ -+ In addition, you need to pass user_debug=N on the kernel command -+ line to enable this feature. N consists of the sum of: -+ -+ 1 - undefined instruction events -+ 2 - system calls -+ 4 - invalid data aborts -+ 8 - SIGSEGV faults -+ 16 - SIGBUS faults -+ -+config DEBUG_ERRORS -+ bool "Verbose kernel error messages" -+ depends on DEBUG_KERNEL -+ help -+ This option controls verbose debugging information which can be -+ printed when the kernel detects an internal error. This debugging -+ information is useful to kernel hackers when tracking down problems, -+ but mostly meaningless to other people. It's safe to say Y unless -+ you are concerned with the code size or don't want to see these -+ messages. -+ -+config DEBUG_LL -+ bool "Kernel low-level debugging functions" -+ depends on DEBUG_KERNEL -+ help -+ Say Y here to include definitions of printascii, printchar, printhex -+ in the kernel. This is helpful if you are debugging code that -+ executes before the console is initialized. -+ -+config CCTL -+ tristate "User space cache control support (EXPERIMENTAL)" -+ depends on EXPERIMENTAL -+ help -+ export cache control to user space via /proc -+ -+ If unsure, say N. -+ -+config ELFCHK_DEFAULT_ENABLE -+ bool "Enable ELF-Core Checking by default" -+ default n -+ select PROC_FS -+ help -+ ELF-Core Checking is a mechanism which prevents ELF binary from -+ being loaded if it requires any feature that the underlying platform -+ doesn't support. -+ -+ If you say Y here, the resulting kernel enables ELF-Core Checking -+ mechanism by default. -+config EARLY_PRINTK -+ bool "Early printk support" -+ default y -+ help -+ Say Y here if you want to have an early console using the -+ earlyprintk=[,][,] kernel parameter. It -+ is assumed that the early console device has been initialised -+ by the boot loader prior to starting the Linux kernel. -+ -+endmenu -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/asm-offsets.c linux-3.4.113/arch/nds32/kernel/asm-offsets.c ---- linux-3.4.113.orig/arch/nds32/kernel/asm-offsets.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/asm-offsets.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,72 @@ -+/* -+ * Copyright (C) 1995-2003 Russell King -+ * 2001-2002 Keith Owens -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * Generate definitions needed by assembly language modules. -+ * This code generates raw asm output which is post-processed to extract -+ * and format the required data. -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * Make sure that the compiler and target are compatible. -+ */ -+ -+#if __GNUC__ < 3 || \ -+ (__GNUC__ == 3 && __GNUC_MINOR__ < 4) || \ -+ (__GNUC__ == 3 && __GNUC_MINOR__ == 4 && __GNUC_PATCHLEVEL__ != 0 && \ -+ __GNUC_PATCHLEVEL__ < 4) || \ -+ (__GNUC__ == 4 && __GNUC_MINOR__ < 2) -+#error Your compiler is too buggy; it is known to miscompile kernels. -+#error Known good compilers: 3.4.4, 4.2 -+#endif -+ -+/* Use marker if you need to separate the values later */ -+ -+#define DEFINE(sym, val) \ -+ asm volatile("\n->" #sym " %0 " #val : : "i" (val)) -+ -+#define BLANK() asm volatile("\n->" : : ) -+ -+int main(void) -+{ -+ DEFINE(TSK_ACTIVE_MM, offsetof(struct task_struct, active_mm)); -+ BLANK(); -+ DEFINE(TI_FLAGS, offsetof(struct thread_info, flags)); -+ DEFINE(TI_PREEMPT, offsetof(struct thread_info, preempt_count)); -+ DEFINE(TI_ADDR_LIMIT, offsetof(struct thread_info, addr_limit)); -+ DEFINE(TI_TASK, offsetof(struct thread_info, task)); -+ DEFINE(TI_EXEC_DOMAIN, offsetof(struct thread_info, exec_domain)); -+ DEFINE(TI_CPU, offsetof(struct thread_info, cpu)); -+// DEFINE(TI_TP_VALUE, offsetof(struct thread_info, tp_value)); -+ DEFINE(TI_SP_SAVE, offsetof(struct thread_info, sp_save)); -+ BLANK(); -+ DEFINE(S_FRAME_SIZE, sizeof(struct pt_regs)); -+ BLANK(); -+ DEFINE(MM_CONTEXT_ID, offsetof(struct mm_struct, context.id)); -+ BLANK(); -+ DEFINE(VMA_VM_MM, offsetof(struct vm_area_struct, vm_mm)); -+ DEFINE(VMA_VM_FLAGS, offsetof(struct vm_area_struct, vm_flags)); -+ BLANK(); -+ DEFINE(VM_EXEC, VM_EXEC); -+ BLANK(); -+ DEFINE(VIRT_OFFSET, PAGE_OFFSET); -+ BLANK(); -+ DEFINE(SIZEOF_MACHINE_DESC, sizeof(struct machine_desc)); -+ DEFINE(MACHINFO_TYPE, offsetof(struct machine_desc, nr)); -+ DEFINE(MACHINFO_NAME, offsetof(struct machine_desc, name)); -+ BLANK(); -+ DEFINE(PROC_INFO_SZ, sizeof(struct proc_info_list)); -+ -+ return 0; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/audio.c linux-3.4.113/arch/nds32/kernel/audio.c ---- linux-3.4.113.orig/arch/nds32/kernel/audio.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/audio.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,218 @@ -+/* -+ * arch/nds32/kernel/audio.c -+ * -+ * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli -+ * Copyright (C) 2002 STMicroelectronics Limited -+ * Author : Stuart Menefy -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * Started from SH4 version: -+ * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "audio.h" -+/* -+ * Initially load the audio with signalling NANS. This bit pattern -+ * has the property that no matter whether considered as single or as -+ * double precision, it still represents a signalling NAN. -+ */ -+ -+static struct audio_struct init_audioregs = { -+ .auregs = {[0...31] = NAN32} -+}; -+ -+void save_audio(struct task_struct *tsk) -+{ -+ unsigned int tmp; -+ enable_audio(); -+ asm volatile ("mfsr %0, $MSC_CFG\n\t" -+ "andi %0, %0, %2\n\t" -+ "srli %0, %0, %3\n\t" -+ "slti %0, %0, 2\n\t" -+ "bnez %0, 99f\n\t" -+ "amfar %0, $D0.L24\n\t" -+ "swi %0, [%1+0x0]\n\t" -+ "amfar %0, $D1.L24\n\t" -+ "swi %0, [%1+0x4]\n\t" -+ "99:\n\t" -+ "amfar %0, $I0\n\t" -+ "swi %0, [%1+0x8]\n\t" -+ "amfar %0, $I1\n\t" -+ "swi %0, [%1+0xc]\n\t" -+ "amfar %0, $I2\n\t" -+ "swi %0, [%1+0x10]\n\t" -+ "amfar %0, $I3\n\t" -+ "swi %0, [%1+0x14]\n\t" -+ "amfar %0, $I4\n\t" -+ "swi %0, [%1+0x18]\n\t" -+ "amfar %0, $I5\n\t" -+ "swi %0, [%1+0x1c]\n\t" -+ "amfar %0, $I6\n\t" -+ "swi %0, [%1+0x20]\n\t" -+ "amfar %0, $I7\n\t" -+ "swi %0, [%1+0x24]\n\t" -+ "amfar %0, $M1\n\t" -+ "swi %0, [%1+0x28]\n\t" -+ "amfar %0, $M2\n\t" -+ "swi %0, [%1+0x2c]\n\t" -+ "amfar %0, $M3\n\t" -+ "swi %0, [%1+0x30]\n\t" -+ "amfar %0, $M5\n\t" -+ "swi %0, [%1+0x34]\n\t" -+ "amfar %0, $M6\n\t" -+ "swi %0, [%1+0x38]\n\t" -+ "amfar %0, $M7\n\t" -+ "swi %0, [%1+0x3c]\n\t" -+ "amfar %0, $MOD\n\t" -+ "swi %0, [%1+0x40]\n\t" -+ "amfar %0, $LB\n\t" -+ "swi %0, [%1+0x44]\n\t" -+ "amfar %0, $LE\n\t" -+ "swi %0, [%1+0x48]\n\t" -+ "amfar %0, $LC\n\t" -+ "swi %0, [%1+0x4c]\n\t" -+ "amfar %0, $ADM_VBASE\n\t" -+ "swi %0, [%1+0x50]\n\t" -+ "amfar %0, $SHFT_CTL0\n\t" -+ "swi %0, [%1+0x54]\n\t" -+ "amfar %0, $SHFT_CTL1\n\t" -+ "swi %0, [%1+0x58]\n\t" -+ "amfar2 %0, $CB_CTL\n\t" -+ "swi %0, [%1+0x5c]\n\t" -+ "amfar2 %0, $CBB0\n\t" -+ "swi %0, [%1+0x60]\n\t" -+ "amfar2 %0, $CBB1\n\t" -+ "swi %0, [%1+0x64]\n\t" -+ "amfar2 %0, $CBB2\n\t" -+ "swi %0, [%1+0x68]\n\t" -+ "amfar2 %0, $CBB3\n\t" -+ "swi %0, [%1+0x6c]\n\t" -+ "amfar2 %0, $CBE0\n\t" -+ "swi %0, [%1+0x70]\n\t" -+ "amfar2 %0, $CBE1\n\t" -+ "swi %0, [%1+0x74]\n\t" -+ "amfar2 %0, $CBE2\n\t" -+ "swi %0, [%1+0x78]\n\t" -+ "amfar2 %0, $CBE3\n\t" -+ "swi %0, [%1+0x7c]\n\t":"=&r" (tmp) -+ :"r"(&tsk->thread.audio), "i"(MSC_CFG_mskAUDIO), -+ "i"(MSC_CFG_offAUDIO) -+ :"memory"); -+ disable_audio(); -+} -+ -+void audioload(struct audio_struct *audioregs) -+{ -+ unsigned int tmp; -+ enable_audio(); -+ asm volatile ("mfsr %0, $MSC_CFG\n\t" -+ "andi %0, %0, %2\n\t" -+ "srli %0, %0, %3\n\t" -+ "slti %0, %0, 2\n\t" -+ "bnez %0, 98f\n\t" -+ "lwi %0, [%1+0x0]\n\t" -+ "amtar %0, $D0.L24\n\t" -+ "lwi %0, [%1+0x4]\n\t" -+ "amtar %0, $D1.L24\n\t" -+ "98:\n\t" -+ "lwi %0, [%1+0x8]\n\t" -+ "amtar %0, $I0\n\t" -+ "lwi %0, [%1+0xc]\n\t" -+ "amtar %0, $I1\n\t" -+ "lwi %0, [%1+0x10]\n\t" -+ "amtar %0, $I2\n\t" -+ "lwi %0, [%1+0x14]\n\t" -+ "amtar %0, $I3\n\t" -+ "lwi %0, [%1+0x18]\n\t" -+ "amtar %0, $I4\n\t" -+ "lwi %0, [%1+0x1c]\n\t" -+ "amtar %0, $I5\n\t" -+ "lwi %0, [%1+0x20]\n\t" -+ "amtar %0, $I6\n\t" -+ "lwi %0, [%1+0x24]\n\t" -+ "amtar %0, $I7\n\t" -+ "lwi %0, [%1+0x28]\n\t" -+ "amtar %0, $M1\n\t" -+ "lwi %0, [%1+0x2c]\n\t" -+ "amtar %0, $M2\n\t" -+ "lwi %0, [%1+0x30]\n\t" -+ "amtar %0, $M3\n\t" -+ "lwi %0, [%1+0x34]\n\t" -+ "amtar %0, $M5\n\t" -+ "lwi %0, [%1+0x38]\n\t" -+ "amtar %0, $M6\n\t" -+ "lwi %0, [%1+0x3c]\n\t" -+ "amtar %0, $M7\n\t" -+ "lwi %0, [%1+0x40]\n\t" -+ "amtar %0, $MOD\n\t" -+ "lwi %0, [%1+0x44]\n\t" -+ "amtar %0, $LB\n\t" -+ "lwi %0, [%1+0x48]\n\t" -+ "amtar %0, $LE\n\t" -+ "lwi %0, [%1+0x4c]\n\t" -+ "amtar %0, $LC\n\t" -+ "lwi %0, [%1+0x50]\n\t" -+ "amtar %0, $ADM_VBASE\n\t" -+ "lwi %0, [%1+0x54]\n\t" -+ "amtar %0, $SHFT_CTL0\n\t" -+ "lwi %0, [%1+0x58]\n\t" -+ "amtar %0, $SHFT_CTL1\n\t" -+ "lwi %0, [%1+0x5c]\n\t" -+ "amtar2 %0, $CB_CTL\n\t" -+ "lwi %0, [%1+0x60]\n\t" -+ "amtar2 %0, $CBB0\n\t" -+ "lwi %0, [%1+0x64]\n\t" -+ "amtar2 %0, $CBB1\n\t" -+ "lwi %0, [%1+0x68]\n\t" -+ "amtar2 %0, $CBB2\n\t" -+ "lwi %0, [%1+0x6c]\n\t" -+ "amtar2 %0, $CBB3\n\t" -+ "lwi %0, [%1+0x70]\n\t" -+ "amtar2 %0, $CBE0\n\t" -+ "lwi %0, [%1+0x74]\n\t" -+ "amtar2 %0, $CBE1\n\t" -+ "lwi %0, [%1+0x78]\n\t" -+ "amtar2 %0, $CBE2\n\t" -+ "lwi %0, [%1+0x7c]\n\t" -+ "amtar2 %0, $CBE3\n\t":"=&r" (tmp) -+ :"r"(audioregs), "i"(MSC_CFG_mskAUDIO), -+ "i"(MSC_CFG_offAUDIO)); -+ disable_audio(); -+} -+ -+void do_audio_context_switch(unsigned long error_code, struct pt_regs *regs) -+{ -+ struct task_struct *tsk = current; -+ -+ if (!user_mode(regs)) -+ die("Audio used in kernel", regs, error_code); -+ -+ /* Enable to use audio. */ -+ grab_audio(regs); -+#ifndef CONFIG_UNLAZY_AUDIO //Lazy audio is used -+ if (last_task_used_audio == current) -+ return; -+ -+ if (last_task_used_audio != NULL) -+ /* Other processes audio state, save away */ -+ save_audio(last_task_used_audio); -+ last_task_used_audio = current; -+#endif -+ if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { -+ audioload(¤t->thread.audio); -+ } else { -+ /* First time audio user. */ -+ audioload(&init_audioregs); -+ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/audio.h linux-3.4.113/arch/nds32/kernel/audio.h ---- linux-3.4.113.orig/arch/nds32/kernel/audio.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/audio.h 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,2 @@ -+ -+#define NAN32 0x0UL -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/bios32.c linux-3.4.113/arch/nds32/kernel/bios32.c ---- linux-3.4.113.orig/arch/nds32/kernel/bios32.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/bios32.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,711 @@ -+/* -+ * linux/arch/nds32/kernel/bios32.c -+ * -+ * PCI bios-type initialisation for PCI machines -+ * -+ * Bits taken from various places. -+ * -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+static int debug_pci; -+static int use_firmware; -+ -+/* -+ * We can't use pci_find_device() here since we are -+ * called from interrupt context. -+ */ -+static void pcibios_bus_report_status(struct pci_bus *bus, u_int status_mask, -+ int warn) -+{ -+ struct pci_dev *dev; -+ -+ list_for_each_entry(dev, &bus->devices, bus_list) { -+ u16 status; -+ -+ /* -+ * ignore host bridge - we handle -+ * that separately -+ */ -+ if (dev->bus->number == 0 && dev->devfn == 0) -+ continue; -+ -+ pci_read_config_word(dev, PCI_STATUS, &status); -+ if (status == 0xffff) -+ continue; -+ -+ if ((status & status_mask) == 0) -+ continue; -+ -+ /* clear the status errors */ -+ pci_write_config_word(dev, PCI_STATUS, status & status_mask); -+ -+ if (warn) -+ printk("(%s: %04X) ", pci_name(dev), status); -+ } -+ -+ list_for_each_entry(dev, &bus->devices, bus_list) -+ if (dev->subordinate) -+ pcibios_bus_report_status(dev->subordinate, status_mask, warn); -+} -+ -+void pcibios_report_status(u_int status_mask, int warn) -+{ -+ struct list_head *l; -+ -+ list_for_each(l, &pci_root_buses) { -+ struct pci_bus *bus = pci_bus_b(l); -+ -+ pcibios_bus_report_status(bus, status_mask, warn); -+ } -+} -+ -+/* -+ * We don't use this to fix the device, but initialisation of it. -+ * It's not the correct use for this, but it works. -+ * Note that the arbiter/ISA bridge appears to be buggy, specifically in -+ * the following area: -+ * 1. park on CPU -+ * 2. ISA bridge ping-pong -+ * 3. ISA bridge master handling of target RETRY -+ * -+ * Bug 3 is responsible for the sound DMA grinding to a halt. We now -+ * live with bug 2. -+ */ -+static void __devinit pci_fixup_83c553(struct pci_dev *dev) -+{ -+ /* -+ * Set memory region to start at address 0, and enable IO -+ */ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, -+ PCI_BASE_ADDRESS_SPACE_MEMORY); -+ pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_IO); -+ -+ dev->resource[0].end -= dev->resource[0].start; -+ dev->resource[0].start = 0; -+ -+ /* -+ * All memory requests from ISA to be channelled to PCI -+ */ -+ pci_write_config_byte(dev, 0x48, 0xff); -+ -+ /* -+ * Enable ping-pong on bus master to ISA bridge transactions. -+ * This improves the sound DMA substantially. The fixed -+ * priority arbiter also helps (see below). -+ */ -+ pci_write_config_byte(dev, 0x42, 0x01); -+ -+ /* -+ * Enable PCI retry -+ */ -+ pci_write_config_byte(dev, 0x40, 0x22); -+ -+ /* -+ * We used to set the arbiter to "park on last master" (bit -+ * 1 set), but unfortunately the CyberPro does not park the -+ * bus. We must therefore park on CPU. Unfortunately, this -+ * may trigger yet another bug in the 553. -+ */ -+ pci_write_config_byte(dev, 0x83, 0x02); -+ -+ /* -+ * Make the ISA DMA request lowest priority, and disable -+ * rotating priorities completely. -+ */ -+ pci_write_config_byte(dev, 0x80, 0x11); -+ pci_write_config_byte(dev, 0x81, 0x00); -+ -+ /* -+ * Route INTA input to IRQ 11, and set IRQ11 to be level -+ * sensitive. -+ */ -+ pci_write_config_word(dev, 0x44, 0xb000); -+ outb(0x08, 0x4d1); -+} -+ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553, -+ pci_fixup_83c553); -+ -+static void __devinit pci_fixup_unassign(struct pci_dev *dev) -+{ -+ dev->resource[0].end -= dev->resource[0].start; -+ dev->resource[0].start = 0; -+} -+ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_WINBOND2, PCI_DEVICE_ID_WINBOND2_89C940F, -+ pci_fixup_unassign); -+ -+/* -+ * Prevent the PCI layer from seeing the resources allocated to this device -+ * if it is the host bridge by marking it as such. These resources are of -+ * no consequence to the PCI layer (they are handled elsewhere). -+ */ -+static void __devinit pci_fixup_dec21285(struct pci_dev *dev) -+{ -+ int i; -+ -+ if (dev->devfn == 0) { -+ dev->class &= 0xff; -+ dev->class |= PCI_CLASS_BRIDGE_HOST << 8; -+ for (i = 0; i < PCI_NUM_RESOURCES; i++) { -+ dev->resource[i].start = 0; -+ dev->resource[i].end = 0; -+ dev->resource[i].flags = 0; -+ } -+ } -+} -+ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285, -+ pci_fixup_dec21285); -+ -+/* -+ * PCI IDE controllers use non-standard I/O port decoding, respect it. -+ */ -+static void __devinit pci_fixup_ide_bases(struct pci_dev *dev) -+{ -+ struct resource *r; -+ int i; -+ -+ if ((dev->class >> 8) != PCI_CLASS_STORAGE_IDE) -+ return; -+ -+ for (i = 0; i < PCI_NUM_RESOURCES; i++) { -+ r = dev->resource + i; -+ if ((r->start & ~0x80) == 0x374) { -+ r->start |= 2; -+ r->end = r->start; -+ } -+ } -+} -+ -+DECLARE_PCI_FIXUP_HEADER(PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases); -+ -+/* -+ * Put the DEC21142 to sleep -+ */ -+static void __devinit pci_fixup_dec21142(struct pci_dev *dev) -+{ -+ pci_write_config_dword(dev, 0x40, 0x80000000); -+} -+ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, -+ pci_fixup_dec21142); -+ -+/* -+ * The CY82C693 needs some rather major fixups to ensure that it does -+ * the right thing. Idea from the Alpha people, with a few additions. -+ * -+ * We ensure that the IDE base registers are set to 1f0/3f4 for the -+ * primary bus, and 170/374 for the secondary bus. Also, hide them -+ * from the PCI subsystem view as well so we won't try to perform -+ * our own auto-configuration on them. -+ * -+ * In addition, we ensure that the PCI IDE interrupts are routed to -+ * IRQ 14 and IRQ 15 respectively. -+ * -+ * The above gets us to a point where the IDE on this device is -+ * functional. However, The CY82C693U _does not work_ in bus -+ * master mode without locking the PCI bus solid. -+ */ -+static void __devinit pci_fixup_cy82c693(struct pci_dev *dev) -+{ -+ if ((dev->class >> 8) == PCI_CLASS_STORAGE_IDE) { -+ u32 base0, base1; -+ -+ if (dev->class & 0x80) { /* primary */ -+ base0 = 0x1f0; -+ base1 = 0x3f4; -+ } else { /* secondary */ -+ base0 = 0x170; -+ base1 = 0x374; -+ } -+ -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_0, -+ base0 | PCI_BASE_ADDRESS_SPACE_IO); -+ pci_write_config_dword(dev, PCI_BASE_ADDRESS_1, -+ base1 | PCI_BASE_ADDRESS_SPACE_IO); -+ -+ dev->resource[0].start = 0; -+ dev->resource[0].end = 0; -+ dev->resource[0].flags = 0; -+ -+ dev->resource[1].start = 0; -+ dev->resource[1].end = 0; -+ dev->resource[1].flags = 0; -+ } else if (PCI_FUNC(dev->devfn) == 0) { -+ /* -+ * Setup IDE IRQ routing. -+ */ -+ pci_write_config_byte(dev, 0x4b, 14); -+ pci_write_config_byte(dev, 0x4c, 15); -+ -+ /* -+ * Disable FREQACK handshake, enable USB. -+ */ -+ pci_write_config_byte(dev, 0x4d, 0x41); -+ -+ /* -+ * Enable PCI retry, and PCI post-write buffer. -+ */ -+ pci_write_config_byte(dev, 0x44, 0x17); -+ -+ /* -+ * Enable ISA master and DMA post write buffering. -+ */ -+ pci_write_config_byte(dev, 0x45, 0x03); -+ } -+} -+ -+DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_CONTAQ, PCI_DEVICE_ID_CONTAQ_82C693, -+ pci_fixup_cy82c693); -+ -+void __devinit pcibios_update_irq(struct pci_dev *dev, int irq) -+{ -+ if (debug_pci) -+ printk("PCI: Assigning IRQ %02d to %s\n", irq, pci_name(dev)); -+ pci_write_config_byte(dev, PCI_INTERRUPT_LINE, irq); -+} -+ -+/* -+ * If the bus contains any of these devices, then we must not turn on -+ * parity checking of any kind. Currently this is CyberPro 20x0 only. -+ */ -+static inline int pdev_bad_for_parity(struct pci_dev *dev) -+{ -+ return (dev->vendor == PCI_VENDOR_ID_INTERG && -+ (dev->device == PCI_DEVICE_ID_INTERG_2000 || -+ dev->device == PCI_DEVICE_ID_INTERG_2010)); -+} -+ -+/* -+ * Adjust the device resources from bus-centric to Linux-centric. -+ */ -+static void __devinit -+pdev_fixup_device_resources(struct pci_sys_data *root, struct pci_dev *dev) -+{ -+ resource_size_t offset; -+ int i; -+ -+ for (i = 0; i < PCI_NUM_RESOURCES; i++) { -+ if (dev->resource[i].start == 0) -+ continue; -+ if (dev->resource[i].flags & IORESOURCE_MEM) -+ offset = root->mem_offset; -+ else -+ offset = root->io_offset; -+ -+ dev->resource[i].start += offset; -+ dev->resource[i].end += offset; -+ } -+} -+ -+static void __devinit -+pbus_assign_bus_resources(struct pci_bus *bus, struct pci_sys_data *root) -+{ -+ struct pci_dev *dev = bus->self; -+ int i; -+ -+ if (!dev) { -+ /* -+ * Assign root bus resources. -+ */ -+ for (i = 0; i < 3; i++) -+ bus->resource[i] = root->resource[i]; -+ } -+} -+ -+/* -+ * pcibios_fixup_bus - Called after each bus is probed, -+ * but before its children are examined. -+ */ -+void __devinit pcibios_fixup_bus(struct pci_bus *bus) -+{ -+ struct pci_sys_data *root = bus->sysdata; -+ struct pci_dev *dev; -+ u16 features = -+ PCI_COMMAND_SERR | PCI_COMMAND_PARITY | PCI_COMMAND_FAST_BACK; -+ -+ pbus_assign_bus_resources(bus, root); -+ -+ /* -+ * Walk the devices on this bus, working out what we can -+ * and can't support. -+ */ -+ list_for_each_entry(dev, &bus->devices, bus_list) { -+ u16 status; -+ -+ pdev_fixup_device_resources(root, dev); -+ -+ pci_read_config_word(dev, PCI_STATUS, &status); -+ -+ /* -+ * If any device on this bus does not support fast back -+ * to back transfers, then the bus as a whole is not able -+ * to support them. Having fast back to back transfers -+ * on saves us one PCI cycle per transaction. -+ */ -+ if (!(status & PCI_STATUS_FAST_BACK)) -+ features &= ~PCI_COMMAND_FAST_BACK; -+ -+ if (pdev_bad_for_parity(dev)) -+ features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); -+ -+ switch (dev->class >> 8) { -+#if defined(CONFIG_ISA) || defined(CONFIG_EISA) -+ case PCI_CLASS_BRIDGE_ISA: -+ case PCI_CLASS_BRIDGE_EISA: -+ /* -+ * If this device is an ISA bridge, set isa_bridge -+ * to point at this device. We will then go looking -+ * for things like keyboard, etc. -+ */ -+ isa_bridge = dev; -+ break; -+#endif -+ case PCI_CLASS_BRIDGE_PCI: -+ pci_read_config_word(dev, PCI_BRIDGE_CONTROL, &status); -+ status |= -+ PCI_BRIDGE_CTL_PARITY | PCI_BRIDGE_CTL_MASTER_ABORT; -+ status &= -+ ~(PCI_BRIDGE_CTL_BUS_RESET | -+ PCI_BRIDGE_CTL_FAST_BACK); -+ pci_write_config_word(dev, PCI_BRIDGE_CONTROL, status); -+ break; -+ -+ case PCI_CLASS_BRIDGE_CARDBUS: -+ pci_read_config_word(dev, PCI_CB_BRIDGE_CONTROL, -+ &status); -+ status |= -+ PCI_CB_BRIDGE_CTL_PARITY | -+ PCI_CB_BRIDGE_CTL_MASTER_ABORT; -+ pci_write_config_word(dev, PCI_CB_BRIDGE_CONTROL, -+ status); -+ break; -+ } -+ } -+ -+ /* -+ * Now walk the devices again, this time setting them up. -+ */ -+ list_for_each_entry(dev, &bus->devices, bus_list) { -+ u16 cmd; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ cmd |= features; -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ -+ pci_write_config_byte(dev, PCI_CACHE_LINE_SIZE, -+ L1_CACHE_BYTES >> 2); -+ } -+ -+ /* -+ * Propagate the flags to the PCI bridge. -+ */ -+ if (bus->self && bus->self->hdr_type == PCI_HEADER_TYPE_BRIDGE) { -+ if (features & PCI_COMMAND_FAST_BACK) -+ bus->bridge_ctl |= PCI_BRIDGE_CTL_FAST_BACK; -+ if (features & PCI_COMMAND_PARITY) -+ bus->bridge_ctl |= PCI_BRIDGE_CTL_PARITY; -+ } -+ -+ /* -+ * Report what we did for this bus -+ */ -+ printk(KERN_INFO "PCI: bus%d: Fast back to back transfers %sabled\n", -+ bus->number, (features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); -+} -+ -+/* -+ * Convert from Linux-centric to bus-centric addresses for bridge devices. -+ */ -+void -+pcibios_resource_to_bus(struct pci_dev *dev, struct pci_bus_region *region, -+ struct resource *res) -+{ -+ struct pci_sys_data *root = dev->sysdata; -+ unsigned long offset = 0; -+ -+ if (res->flags & IORESOURCE_IO) -+ offset = root->io_offset; -+ if (res->flags & IORESOURCE_MEM) -+ offset = root->mem_offset; -+ -+ region->start = res->start - offset; -+ region->end = res->end - offset; -+} -+ -+void __devinit -+pcibios_bus_to_resource(struct pci_dev *dev, struct resource *res, -+ struct pci_bus_region *region) -+{ -+ struct pci_sys_data *root = dev->sysdata; -+ unsigned long offset = 0; -+ -+ if (res->flags & IORESOURCE_IO) -+ offset = root->io_offset; -+ if (res->flags & IORESOURCE_MEM) -+ offset = root->mem_offset; -+ -+ res->start = region->start + offset; -+ res->end = region->end + offset; -+} -+ -+#ifdef CONFIG_HOTPLUG -+EXPORT_SYMBOL(pcibios_fixup_bus); -+EXPORT_SYMBOL(pcibios_resource_to_bus); -+EXPORT_SYMBOL(pcibios_bus_to_resource); -+#endif -+ -+/* -+ * This is the standard PCI-PCI bridge swizzling algorithm: -+ * -+ * Dev: 0 1 2 3 -+ * A A B C D -+ * B B C D A -+ * C C D A B -+ * D D A B C -+ * ^^^^^^^^^^ irq pin on bridge -+ */ -+u8 __devinit pci_std_swizzle(struct pci_dev *dev, u8 * pinp) -+{ -+ int pin = *pinp - 1; -+ -+ while (dev->bus->self) { -+ pin = (pin + PCI_SLOT(dev->devfn)) & 3; -+ /* -+ * move up the chain of bridges, -+ * swizzling as we go. -+ */ -+ dev = dev->bus->self; -+ } -+ *pinp = pin + 1; -+ -+ return PCI_SLOT(dev->devfn); -+} -+ -+/* -+ * Swizzle the device pin each time we cross a bridge. -+ * This might update pin and returns the slot number. -+ */ -+static u8 __devinit pcibios_swizzle(struct pci_dev *dev, u8 * pin) -+{ -+ struct pci_sys_data *sys = dev->sysdata; -+ int slot = 0, oldpin = *pin; -+ -+ if (sys->swizzle) -+ slot = sys->swizzle(dev, pin); -+ -+ if (debug_pci) -+ printk("PCI: %s swizzling pin %d => pin %d slot %d\n", -+ pci_name(dev), oldpin, *pin, slot); -+ -+ return slot; -+} -+ -+/* -+ * Map a slot/pin to an IRQ. -+ */ -+static int pcibios_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ struct pci_sys_data *sys = dev->sysdata; -+ int irq = -1; -+ -+ if (sys->map_irq) -+ irq = sys->map_irq(dev, slot, pin); -+ -+ if (debug_pci) -+ printk("PCI: %s mapping slot %d pin %d => irq %d\n", -+ pci_name(dev), slot, pin, irq); -+ -+ return irq; -+} -+ -+static void __init pcibios_init_hw(struct hw_pci *hw) -+{ -+ struct pci_sys_data *sys = NULL; -+ int ret; -+ int nr, busnr; -+ -+ for (nr = busnr = 0; nr < hw->nr_controllers; nr++) { -+ sys = kmalloc(sizeof(struct pci_sys_data), GFP_KERNEL); -+ if (!sys) -+ panic("PCI: unable to allocate sys data!"); -+ -+ memset(sys, 0, sizeof(struct pci_sys_data)); -+ -+ sys->hw = hw; -+ sys->busnr = busnr; -+ sys->swizzle = hw->swizzle; -+ sys->map_irq = hw->map_irq; -+ sys->resource[0] = &ioport_resource; -+ sys->resource[1] = &iomem_resource; -+ -+ ret = hw->setup(nr, sys); -+ -+ if (ret > 0) { -+ sys->bus = hw->scan(nr, sys); -+ -+ if (!sys->bus) -+ panic("PCI: unable to scan bus!"); -+ -+ busnr = sys->bus->subordinate + 1; -+ -+ list_add(&sys->node, &hw->buses); -+ } else { -+ kfree(sys); -+ if (ret < 0) -+ break; -+ } -+ } -+} -+ -+void __init pci_common_init(struct hw_pci *hw) -+{ -+ struct pci_sys_data *sys; -+ -+ INIT_LIST_HEAD(&hw->buses); -+ -+ if (hw->preinit) -+ hw->preinit(); -+ pcibios_init_hw(hw); -+ if (hw->postinit) -+ hw->postinit(); -+ -+ pci_fixup_irqs(pcibios_swizzle, pcibios_map_irq); -+ -+ list_for_each_entry(sys, &hw->buses, node) { -+ struct pci_bus *bus = sys->bus; -+ -+ if (!use_firmware) { -+ /* -+ * Size the bridge windows. -+ */ -+ pci_bus_size_bridges(bus); -+ -+ /* -+ * Assign resources. -+ */ -+ pci_bus_assign_resources(bus); -+ } -+ -+ /* -+ * Tell drivers about devices found. -+ */ -+ pci_bus_add_devices(bus); -+ } -+} -+ -+char *__devinit pcibios_setup(char *str) -+{ -+ if (!strcmp(str, "debug")) { -+ debug_pci = 1; -+ return NULL; -+ } else if (!strcmp(str, "firmware")) { -+ use_firmware = 1; -+ return NULL; -+ } -+ return str; -+} -+ -+/* -+ * From arch/i386/kernel/pci-i386.c: -+ * -+ * We need to avoid collisions with `mirrored' VGA ports -+ * and other strange ISA hardware, so we always want the -+ * addresses to be allocated in the 0x000-0x0ff region -+ * modulo 0x400. -+ * -+ * Why? Because some silly external IO cards only decode -+ * the low 10 bits of the IO address. The 0x00-0xff region -+ * is reserved for motherboard devices that decode all 16 -+ * bits, so it's ok to allocate at, say, 0x2800-0x28ff, -+ * but we want to try to avoid allocating at 0x2900-0x2bff -+ * which might be mirrored at 0x0100-0x03ff.. -+ */ -+void pcibios_align_resource(void *data, struct resource *res, -+ resource_size_t size, resource_size_t align) -+{ -+ resource_size_t start = res->start; -+ -+ if (res->flags & IORESOURCE_IO && start & 0x300) -+ start = (start + 0x3ff) & ~0x3ff; -+ -+ res->start = (start + align - 1) & ~(align - 1); -+} -+ -+/** -+ * pcibios_enable_device - Enable I/O and memory. -+ * @dev: PCI device to be enabled -+ */ -+int pcibios_enable_device(struct pci_dev *dev, int mask) -+{ -+ u16 cmd, old_cmd; -+ int idx; -+ struct resource *r; -+ -+ pci_read_config_word(dev, PCI_COMMAND, &cmd); -+ old_cmd = cmd; -+ for (idx = 0; idx < 6; idx++) { -+ /* Only set up the requested stuff */ -+ if (!(mask & (1 << idx))) -+ continue; -+ -+ r = dev->resource + idx; -+ if (!r->start && r->end) { -+ printk(KERN_ERR "PCI: Device %s not available because" -+ " of resource collisions\n", pci_name(dev)); -+ return -EINVAL; -+ } -+ if (r->flags & IORESOURCE_IO) -+ cmd |= PCI_COMMAND_IO; -+ if (r->flags & IORESOURCE_MEM) -+ cmd |= PCI_COMMAND_MEMORY; -+ } -+ -+ /* -+ * Bridges (eg, cardbus bridges) need to be fully enabled -+ */ -+ if ((dev->class >> 16) == PCI_BASE_CLASS_BRIDGE) -+ cmd |= PCI_COMMAND_IO | PCI_COMMAND_MEMORY; -+ -+ if (cmd != old_cmd) { -+ printk("PCI: enabling device %s (%04x -> %04x)\n", -+ pci_name(dev), old_cmd, cmd); -+ pci_write_config_word(dev, PCI_COMMAND, cmd); -+ } -+ return 0; -+} -+ -+int pci_mmap_page_range(struct pci_dev *dev, struct vm_area_struct *vma, -+ enum pci_mmap_state mmap_state, int write_combine) -+{ -+ struct pci_sys_data *root = dev->sysdata; -+ unsigned long phys; -+ -+ if (mmap_state == pci_mmap_io) { -+ return -EINVAL; -+ } else { -+ phys = vma->vm_pgoff + (root->mem_offset >> PAGE_SHIFT); -+ } -+ -+ /* -+ * Mark this as IO -+ */ -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ -+ if (remap_pfn_range(vma, vma->vm_start, phys, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot)) -+ return -EAGAIN; -+ -+ return 0; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/calls.S linux-3.4.113/arch/nds32/kernel/calls.S ---- linux-3.4.113.orig/arch/nds32/kernel/calls.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/calls.S 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,400 @@ -+/* -+ * linux/arch/nds32/kernel/calls.S -+ * -+ * Copyright (C) 1995-2004 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * This file is included twice in entry-common.S -+ */ -+ -+/* 0 */ CALL(sys_restart_syscall) -+ CALL(sys_exit) -+ CALL(sys_fork_wrapper) -+ CALL(sys_read) -+ CALL(sys_write) -+/* 5 */ CALL(sys_open) -+ CALL(sys_close) -+ CALL(sys_waitpid) -+ CALL(sys_creat) -+ CALL(sys_link) -+/* 10 */ CALL(sys_unlink) -+ CALL(sys_execve_wrapper) -+ CALL(sys_chdir) -+ CALL(sys_time) /* used by libc4 */ -+ CALL(sys_mknod) -+/* 15 */ CALL(sys_chmod) -+ CALL(sys_lchown16) -+ CALL(sys_ni_syscall) /* was sys_break */ -+ CALL(sys_ni_syscall) /* was sys_stat */ -+ CALL(sys_lseek) -+/* 20 */ CALL(sys_getpid) -+ CALL(sys_mount) -+ CALL(sys_oldumount) /* used by libc4 */ -+ CALL(sys_setuid16) -+ CALL(sys_getuid16) -+/* 25 */ CALL(sys_stime) -+ CALL(sys_ptrace) -+ CALL(sys_alarm) /* used by libc4 */ -+ CALL(sys_ni_syscall) /* was sys_fstat */ -+ CALL(sys_pause) -+/* 30 */ CALL(sys_utime) /* used by libc4 */ -+ CALL(sys_ni_syscall) /* was sys_stty */ -+ CALL(sys_ni_syscall) /* was sys_getty */ -+ CALL(sys_access) -+ CALL(sys_nice) -+/* 35 */ CALL(sys_ni_syscall) /* was sys_ftime */ -+ CALL(sys_sync) -+ CALL(sys_kill) -+ CALL(sys_rename) -+ CALL(sys_mkdir) -+/* 40 */ CALL(sys_rmdir) -+ CALL(sys_dup) -+ CALL(sys_pipe) -+ CALL(sys_times) -+ CALL(sys_ni_syscall) /* was sys_prof */ -+/* 45 */ CALL(sys_brk) -+ CALL(sys_setgid16) -+ CALL(sys_getgid16) -+ CALL(sys_ni_syscall) /* was sys_signal */ -+ CALL(sys_geteuid16) -+/* 50 */ CALL(sys_getegid16) -+ CALL(sys_acct) -+ CALL(sys_umount) -+ CALL(sys_ni_syscall) /* was sys_lock */ -+ CALL(sys_ioctl) -+/* 55 */ CALL(sys_fcntl) -+ CALL(sys_ni_syscall) /* was sys_mpx */ -+ CALL(sys_setpgid) -+ CALL(sys_ni_syscall) /* was sys_ulimit */ -+ CALL(sys_cacheflush) /* was sys_olduname */ -+/* 60 */ CALL(sys_umask) -+ CALL(sys_chroot) -+ CALL(sys_ustat) -+ CALL(sys_dup2) -+ CALL(sys_getppid) -+/* 65 */ CALL(sys_getpgrp) -+ CALL(sys_setsid) -+ CALL(sys_sigaction) -+ CALL(sys_ni_syscall) /* was sys_sgetmask */ -+ CALL(sys_ni_syscall) /* was sys_ssetmask */ -+/* 70 */ CALL(sys_setreuid16) -+ CALL(sys_setregid16) -+ CALL(sys_sigsuspend_wrapper) -+ CALL(sys_sigpending) -+ CALL(sys_sethostname) -+/* 75 */ CALL(sys_setrlimit) -+ CALL(sys_old_getrlimit) /* used by libc4 */ -+ CALL(sys_getrusage) -+ CALL(sys_gettimeofday) -+ CALL(sys_settimeofday) -+/* 80 */ CALL(sys_getgroups16) -+ CALL(sys_setgroups16) -+ CALL(old_select) /* used by libc4 */ -+ CALL(sys_symlink) -+ CALL(sys_ni_syscall) /* was sys_lstat */ -+/* 85 */ CALL(sys_readlink) -+ CALL(sys_uselib) -+ CALL(sys_swapon) -+ CALL(sys_reboot) -+ CALL(sys_old_readdir) /* used by libc4 */ -+/* 90 */ CALL(sys_old_mmap) /* used by libc4 */ -+ CALL(sys_munmap) -+ CALL(sys_truncate) -+ CALL(sys_ftruncate) -+ CALL(sys_fchmod) -+/* 95 */ CALL(sys_fchown16) -+ CALL(sys_getpriority) -+ CALL(sys_setpriority) -+ CALL(sys_ni_syscall) /* was sys_profil */ -+ CALL(sys_statfs) -+/* 100 */ CALL(sys_fstatfs) -+ CALL(sys_ni_syscall) -+ CALL(sys_socketcall) -+ CALL(sys_syslog) -+ CALL(sys_setitimer) -+/* 105 */ CALL(sys_getitimer) -+ CALL(sys_newstat) -+ CALL(sys_newlstat) -+ CALL(sys_newfstat) -+ CALL(sys_ni_syscall) /* was sys_uname */ -+/* 110 */ CALL(sys_ni_syscall) /* was sys_iopl */ -+ CALL(sys_vhangup) -+ CALL(sys_ni_syscall) -+ CALL(sys_syscall) /* call a syscall */ -+ CALL(sys_wait4) -+/* 115 */ CALL(sys_swapoff) -+ CALL(sys_sysinfo) -+ CALL(sys_ipc) -+ CALL(sys_fsync) -+ CALL(sys_sigreturn_wrapper) -+/* 120 */ CALL(sys_clone_wrapper) -+ CALL(sys_setdomainname) -+ CALL(sys_newuname) -+ CALL(sys_ni_syscall) -+ CALL(sys_adjtimex) -+/* 125 */ CALL(sys_mprotect) -+ CALL(sys_sigprocmask) -+ CALL(sys_ni_syscall) /* was sys_create_module */ -+ CALL(sys_init_module) -+ CALL(sys_delete_module) -+/* 130 */ CALL(sys_ni_syscall) /* was sys_get_kernel_syms */ -+ CALL(sys_quotactl) -+ CALL(sys_getpgid) -+ CALL(sys_fchdir) -+ CALL(sys_bdflush) -+/* 135 */ CALL(sys_sysfs) -+ CALL(sys_personality) -+ CALL(sys_ni_syscall) /* was _sys_afs_syscall */ -+ CALL(sys_setfsuid16) -+ CALL(sys_setfsgid16) -+/* 140 */ CALL(sys_llseek) -+ CALL(sys_getdents) -+ CALL(sys_select) -+ CALL(sys_flock) -+ CALL(sys_msync) -+/* 145 */ CALL(sys_readv) -+ CALL(sys_writev) -+ CALL(sys_getsid) -+ CALL(sys_fdatasync) -+ CALL(sys_sysctl) -+/* 150 */ CALL(sys_mlock) -+ CALL(sys_munlock) -+ CALL(sys_mlockall) -+ CALL(sys_munlockall) -+ CALL(sys_sched_setparam) -+/* 155 */ CALL(sys_sched_getparam) -+ CALL(sys_sched_setscheduler) -+ CALL(sys_sched_getscheduler) -+ CALL(sys_sched_yield) -+ CALL(sys_sched_get_priority_max) -+/* 160 */ CALL(sys_sched_get_priority_min) -+ CALL(sys_sched_rr_get_interval) -+ CALL(sys_nanosleep) -+ CALL(sys_nds32_mremap) -+ CALL(sys_setresuid16) -+/* 165 */ CALL(sys_getresuid16) -+ CALL(sys_getpagesize) -+ CALL(sys_ni_syscall) /* was sys_query_module */ -+ CALL(sys_poll) -+ CALL(sys_ni_syscall) /* was nfsservctl */ -+/* 170 */ CALL(sys_setresgid16) -+ CALL(sys_getresgid16) -+ CALL(sys_prctl) -+ CALL(sys_rt_sigreturn_wrapper) -+ CALL(sys_rt_sigaction) -+/* 175 */ CALL(sys_rt_sigprocmask) -+ CALL(sys_rt_sigpending) -+ CALL(sys_rt_sigtimedwait) -+ CALL(sys_rt_sigqueueinfo) -+ CALL(sys_rt_sigsuspend_wrapper) -+/* 180 */ CALL(sys_pread64) -+ CALL(sys_pwrite64) -+ CALL(sys_chown16) -+ CALL(sys_getcwd) -+ CALL(sys_capget) -+/* 185 */ CALL(sys_capset) -+ CALL(sys_sigaltstack_wrapper) -+ CALL(sys_sendfile) -+ CALL(sys_ni_syscall) -+ CALL(sys_ni_syscall) -+/* 190 */ CALL(sys_vfork_wrapper) -+ CALL(sys_getrlimit) -+ CALL(sys_mmap2) -+ CALL(sys_truncate64) -+ CALL(sys_ftruncate64) -+/* 195 */ CALL(sys_stat64) -+ CALL(sys_lstat64) -+ CALL(sys_fstat64) -+ CALL(sys_lchown) -+ CALL(sys_getuid) -+/* 200 */ CALL(sys_getgid) -+ CALL(sys_geteuid) -+ CALL(sys_getegid) -+ CALL(sys_setreuid) -+ CALL(sys_setregid) -+/* 205 */ CALL(sys_getgroups) -+ CALL(sys_setgroups) -+ CALL(sys_fchown) -+ CALL(sys_setresuid) -+ CALL(sys_getresuid) -+/* 210 */ CALL(sys_setresgid) -+ CALL(sys_getresgid) -+ CALL(sys_chown) -+ CALL(sys_setuid) -+ CALL(sys_setgid) -+/* 215 */ CALL(sys_setfsuid) -+ CALL(sys_setfsgid) -+ CALL(sys_getdents64) -+ CALL(sys_pivot_root) -+ CALL(sys_mincore) -+/* 220 */ CALL(sys_madvise) -+ CALL(sys_fcntl64) -+ CALL(sys_ni_syscall) /* TUX */ -+ CALL(sys_ni_syscall) -+ CALL(sys_gettid) -+/* 225 */ CALL(sys_readahead) -+ CALL(sys_setxattr) -+ CALL(sys_lsetxattr) -+ CALL(sys_fsetxattr) -+ CALL(sys_getxattr) -+/* 230 */ CALL(sys_lgetxattr) -+ CALL(sys_fgetxattr) -+ CALL(sys_listxattr) -+ CALL(sys_llistxattr) -+ CALL(sys_flistxattr) -+/* 235 */ CALL(sys_removexattr) -+ CALL(sys_lremovexattr) -+ CALL(sys_fremovexattr) -+ CALL(sys_tkill) -+ CALL(sys_sendfile64) -+/* 240 */ CALL(sys_futex_wrapper) -+ CALL(sys_sched_setaffinity) -+ CALL(sys_sched_getaffinity) -+ CALL(sys_io_setup) -+ CALL(sys_io_destroy) -+/* 245 */ CALL(sys_io_getevents) -+ CALL(sys_io_submit) -+ CALL(sys_io_cancel) -+ CALL(sys_exit_group) -+ CALL(sys_lookup_dcookie) -+/* 250 */ CALL(sys_epoll_create) -+ CALL(sys_epoll_ctl) -+ CALL(sys_epoll_wait) -+ CALL(sys_remap_file_pages) -+ CALL(sys_ni_syscall) /* sys_set_thread_area */ -+/* 255 */ CALL(sys_ni_syscall) /* sys_get_thread_area */ -+ CALL(sys_set_tid_address) -+ CALL(sys_timer_create) -+ CALL(sys_timer_settime) -+ CALL(sys_timer_gettime) -+/* 260 */ CALL(sys_timer_getoverrun) -+ CALL(sys_timer_delete) -+ CALL(sys_clock_settime) -+ CALL(sys_clock_gettime) -+ CALL(sys_clock_getres) -+/* 265 */ CALL(sys_clock_nanosleep) -+ CALL(sys_statfs64) -+ CALL(sys_fstatfs64) -+ CALL(sys_tgkill) -+ CALL(sys_utimes) -+/* 270 */ CALL(sys_fadvise64_64_wrapper) -+ CALL(sys_pciconfig_iobase) -+ CALL(sys_pciconfig_read) -+ CALL(sys_pciconfig_write) -+ CALL(sys_mq_open) -+/* 275 */ CALL(sys_mq_unlink) -+ CALL(sys_mq_timedsend) -+ CALL(sys_mq_timedreceive) -+ CALL(sys_mq_notify) -+ CALL(sys_mq_getsetattr) -+/* 280 */ CALL(sys_waitid) -+ CALL(sys_add_key) -+ CALL(sys_request_key) -+ CALL(sys_keyctl) -+ CALL(sys_ioprio_set) -+/* 285 */ CALL(sys_ioprio_get) -+ CALL(sys_inotify_init) -+ CALL(sys_inotify_add_watch) -+ CALL(sys_inotify_rm_watch) -+ CALL(sys_migrate_pages) -+/* 290 */ CALL(sys_openat) -+ CALL(sys_mkdirat) -+ CALL(sys_mknodat) -+ CALL(sys_fchownat) -+ CALL(sys_futimesat) -+/* 295 */ CALL(sys_fstatat64) -+ CALL(sys_unlinkat) -+ CALL(sys_renameat) -+ CALL(sys_linkat) -+ CALL(sys_symlinkat) -+/* 300 */ CALL(sys_readlinkat) -+ CALL(sys_fchmodat) -+ CALL(sys_faccessat) -+ CALL(sys_pselect6) /* sys_pselect6 */ -+ CALL(sys_ppoll) /* sys_ppoll */ -+/* 305 */ CALL(sys_unshare) -+ CALL(sys_set_robust_list) -+ CALL(sys_get_robust_list) -+ CALL(sys_splice) -+ CALL(sys_sync_file_range2) -+/* 310 */ CALL(sys_tee) -+ CALL(sys_vmsplice) -+ CALL(sys_move_pages) -+ CALL(sys_fadvise64) -+ CALL(sys_utimensat) -+/* 315 */ CALL(sys_signalfd) -+ CALL(sys_timerfd_create) -+ CALL(sys_eventfd) -+ CALL(sys_fallocate) -+ CALL(sys_timerfd_settime) -+/* 320 */ CALL(sys_timerfd_gettime) -+ CALL(sys_getcpu) -+ CALL(sys_signalfd4) -+ CALL(sys_eventfd2) -+ CALL(sys_epoll_create1) -+/* 325 */ CALL(sys_dup3) -+ CALL(sys_pipe2) -+ CALL(sys_inotify_init1) -+ CALL(sys_kexec_load) -+ CALL(sys_accept) -+/* 330 */ CALL(sys_bind) -+ CALL(sys_connect) -+ CALL(sys_getpeername) -+ CALL(sys_getsockname) -+ CALL(sys_getsockopt) -+/* 335 */ CALL(sys_listen) -+ CALL(sys_recv) -+ CALL(sys_recvfrom) -+ CALL(sys_recvmsg) -+ CALL(sys_send) -+/* 340 */ CALL(sys_sendmsg) -+ CALL(sys_sendto) -+ CALL(sys_setsockopt) -+ CALL(sys_shutdown) -+ CALL(sys_socket) -+/* 345 */ CALL(sys_socketpair) -+ CALL(sys_prlimit64) -+ CALL(sys_accept4) -+ CALL(sys_recvmmsg) -+ CALL(sys_sendmmsg) -+/* 350 */ CALL(sys_fanotify_init) -+ CALL(sys_fanotify_mark) -+ CALL(sys_msgget) -+ CALL(sys_msgctl) -+ CALL(sys_msgrcv) -+/* 355 */ CALL(sys_msgsnd) -+ CALL(sys_semget) -+ CALL(sys_semctl) -+ CALL(sys_semtimedop) -+ CALL(sys_semop) -+/* 360 */ CALL(sys_shmget) -+ CALL(sys_shmctl) -+ CALL(sys_shmat) -+ CALL(sys_shmdt) -+ CALL(sys_syncfs) -+/* 365 */ CALL(sys_setns) -+ CALL(sys_name_to_handle_at) -+ CALL(sys_open_by_handle_at) -+ CALL(sys_process_vm_readv) -+ CALL(sys_process_vm_writev) -+/* 370 */ CALL(sys_clock_adjtime) -+ CALL(sys_get_mempolicy) -+ CALL(sys_mbind) -+ CALL(sys_perf_event_open) -+ CALL(sys_preadv) -+/* 375 */ CALL(sys_pwritev) -+ CALL(sys_rt_tgsigqueueinfo) -+ CALL(sys_set_mempolicy) -+ CALL(sys_epoll_pwait) -+ -+#ifndef syscalls_counted -+.equ syscalls_padding, ((NR_syscalls + 3) & ~3) - NR_syscalls -+#define syscalls_counted -+#endif -+ .rept syscalls_padding -+ CALL(sys_ni_syscall) -+ .endr -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/early_printk.c linux-3.4.113/arch/nds32/kernel/early_printk.c ---- linux-3.4.113.orig/arch/nds32/kernel/early_printk.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/early_printk.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,126 @@ -+/* -+ * Earlyprintk support. -+ * -+ * Copyright (C) 2012 ARM Ltd. -+ * Author: Catalin Marinas -+ * -+ * 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. -+ * -+ * 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, see . -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+extern void __iomem *early_io_map(phys_addr_t phys); -+static void __iomem *early_base; -+static void (*printch) (char ch); -+ -+/* -+ * 8250/16550 (8-bit aligned registers) single character TX. -+ */ -+static void uart8250_8bit_printch(char ch) -+{ -+ while (!(readb(early_base + UART_LSR) & UART_LSR_THRE)) ; -+ writeb(ch, early_base + UART_TX); -+} -+ -+/* -+ * 8250/16550 (32-bit aligned registers) single character TX. -+ */ -+static void uart8250_32bit_printch(char ch) -+{ -+ while (!(readl(early_base + (UART_LSR << 2)) & UART_LSR_THRE)) ; -+ writel(ch, early_base + (UART_TX << 2)); -+} -+ -+struct earlycon_match { -+ const char *name; -+ void (*printch) (char ch); -+}; -+ -+static const struct earlycon_match earlycon_match[] __initconst = { -+ {.name = "uart8250-8bit",.printch = uart8250_8bit_printch,}, -+ {.name = "uart8250-32bit",.printch = uart8250_32bit_printch,}, -+ {} -+}; -+ -+static void early_write(struct console *con, const char *s, unsigned n) -+{ -+ while (n-- > 0) { -+ if (*s == '\n') -+ printch('\r'); -+ printch(*s); -+ s++; -+ } -+} -+ -+static struct console early_console_dev = { -+ .name = "earlycon", -+ .write = early_write, -+ .flags = CON_PRINTBUFFER | CON_BOOT, -+ .index = -1, -+}; -+ -+/* -+ * Parse earlyprintk=... parameter in the format: -+ * -+ * [,][,] -+ * -+ * and register the early console. It is assumed that the UART has been -+ * initialised by the bootloader already. -+ */ -+static int __init setup_early_printk(char *buf) -+{ -+ const struct earlycon_match *match = earlycon_match; -+ phys_addr_t paddr = 0; -+ -+ if (!buf) { -+ pr_warning("No earlyprintk arguments passed.\n"); -+ return 0; -+ } -+ -+ while (match->name) { -+ size_t len = strlen(match->name); -+ if (!strncmp(buf, match->name, len)) { -+ buf += len; -+ break; -+ } -+ match++; -+ } -+ if (!match->name) { -+ pr_warning("Unknown earlyprintk arguments: %s\n", buf); -+ return 0; -+ } -+ -+ /* I/O address */ -+ if (!strncmp(buf, ",0x", 3)) { -+ char *e; -+ paddr = simple_strtoul(buf + 1, &e, 16); -+ buf = e; -+ } -+ -+ if (paddr) -+ early_base = early_io_map(paddr); -+ printch = match->printch; -+ //early_console = &early_console_dev; -+ register_console(&early_console_dev); -+ -+ return 0; -+} -+ -+early_param("earlyprintk", setup_early_printk); -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/elfchk.c linux-3.4.113/arch/nds32/kernel/elfchk.c ---- linux-3.4.113.orig/arch/nds32/kernel/elfchk.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/elfchk.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,190 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ELF_CHECKING_OS -+#include "nds32-elf.h" -+ -+extern struct proc_dir_entry *proc_dir_cpu; -+ -+#ifdef CONFIG_ELFCHK_DEFAULT_ENABLE -+static int elf_check_en = 1; -+#else -+static int elf_check_en = 0; -+#endif -+ -+struct reg_struct { -+ -+ const char *name; -+ int idx; -+}; -+ -+static struct reg_struct regs[] = { -+ -+ {"cpu_ver", CPU_SR_INDEX(0, 0, 0)}, -+ {"icm_cfg", CPU_SR_INDEX(0, 1, 0)}, -+ {"dcm_cfg", CPU_SR_INDEX(0, 2, 0)}, -+ {"mmu_cfg", CPU_SR_INDEX(0, 3, 0)}, -+ {"msc_cfg", CPU_SR_INDEX(0, 4, 0)}, -+#ifdef CONFIG_FPU -+ {"fucop_exist", CPU_SR_INDEX(0, 5, 0)} -+#endif -+}; -+ -+#ifdef CONFIG_FPU -+static unsigned int read_fpu_fpcfg(void) -+{ -+ unsigned int fpcfg = 0; -+ -+ enable_fpu(); -+ asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg)); -+ disable_fpu(); -+ -+ return fpcfg; -+} -+#endif -+ -+static unsigned int read_cpu_sr(unsigned int idx) -+{ -+ switch (idx) { -+ -+ case CPU_SR_INDEX(0, 0, 0): -+ return GET_CPU_VER(); -+ case CPU_SR_INDEX(0, 1, 0): -+ return GET_ICM_CFG(); -+ case CPU_SR_INDEX(0, 2, 0): -+ return GET_DCM_CFG(); -+ case CPU_SR_INDEX(0, 3, 0): -+ return GET_MMU_CFG(); -+ case CPU_SR_INDEX(0, 4, 0): -+ return GET_MSC_CFG(); -+ case CPU_SR_INDEX(0, 5, 0): -+ return GET_FUCOP_EXIST(); -+ -+ default: -+ printk(KERN_ERR -+ "%s: invalid system register index (%d, %d, %d)\n", -+ __func__, (idx >> 7) & 0x7, (idx >> 3) & 0xf, idx & 0x7); -+ -+ return SR_NOT_EXIST; -+ } -+} -+ -+static unsigned int reg_read_callback(unsigned int idx) -+{ -+ if (HW_IS_CPU(idx)) { -+ -+ return read_cpu_sr(SR_INDEX(idx)); -+ } else if (HW_IS_FPU(idx)) { -+ -+#ifdef CONFIG_FPU -+ if (SR_FPU_FPCFG == SR_INDEX(idx)) -+ return read_fpu_fpcfg(); -+ else -+ return SR_NOT_EXIST; -+#endif -+ } else if (HW_IS_AUDIO(idx)) { -+ -+ return SR_NOT_EXIST; -+ } -+ -+ return SR_NOT_EXIST; -+} -+ -+#define BUFLEN 1024 -+ -+int do_elf_check_arch(const struct elf32_hdr *hdr) -+{ -+ static char msg_buf[BUFLEN]; -+ unsigned int err; -+ int buf_status = 0; -+ -+ if (!elf_check_en) -+ return 1; -+ -+ err = -+ elf_check((void *)hdr, reg_read_callback, msg_buf, BUFLEN, -+ &buf_status); -+ -+ if (err) -+ printk(KERN_WARNING "%s", msg_buf); -+ -+ return !err; -+} -+ -+static int proc_elf_check_read(char *page, char **start, off_t off, int count, -+ int *eof, void *data) -+{ -+ return sprintf(page, "%d\n", elf_check_en); -+} -+ -+#define INPUTLEN 10 -+static int proc_elf_check_write(struct file *file, const char __user * buffer, -+ unsigned long count, void *data) -+{ -+ unsigned long en; -+ char inbuf[INPUTLEN]; -+ -+ if (count > INPUTLEN - 1) -+ count = INPUTLEN - 1; -+ -+ if (copy_from_user(inbuf, buffer, count)) -+ return -EFAULT; -+ -+ inbuf[count] = '\0'; -+ -+ if (!sscanf(inbuf, "%lu", &en) || en > 3) -+ return -EFAULT; -+ -+ elf_check_en = en & 0x01; -+ -+ return count; -+} -+ -+static int proc_elf_check_read_reg(char *page, char **start, -+ off_t off, int count, int *eof, void *data) -+{ -+ unsigned long val = read_cpu_sr(*(int *)data); -+ -+ return sprintf(page, "0x%08lx\n", val); -+} -+ -+int __init elf_check_init(void) -+{ -+ static struct proc_dir_entry *res_elf_check; -+ int i; -+ -+ if (!proc_dir_cpu) { -+ if (!(proc_dir_cpu = proc_mkdir("cpu", NULL))) -+ return -ENOMEM; -+ } -+ -+ res_elf_check = -+ create_proc_entry("elf_core_checking", S_IWUSR | S_IRUGO, -+ proc_dir_cpu); -+ if (!res_elf_check) -+ return -ENOMEM; -+ -+ res_elf_check->read_proc = proc_elf_check_read; -+ res_elf_check->write_proc = proc_elf_check_write; -+ -+ for (i = 0; i < ARRAY_SIZE(regs); i++) { -+ -+ if (!create_proc_read_entry(regs[i].name, S_IWUSR | S_IRUGO, -+ proc_dir_cpu, -+ proc_elf_check_read_reg, -+ ®s[i].idx)) -+ -+ return -ENOMEM; -+ } -+ -+ return 0; -+} -+ -+module_init(elf_check_init); -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/ex-entry.S linux-3.4.113/arch/nds32/kernel/ex-entry.S ---- linux-3.4.113.orig/arch/nds32/kernel/ex-entry.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/ex-entry.S 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,294 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ .macro push_zol -+#ifdef CONFIG_HWZOL -+ mfusr $r10, $LB -+ mfusr $r11, $LE -+ mfusr $r12, $LC -+#endif -+ .endm -+ .macro save_user_regs -+ /* $p1 is VA of percpu data */ -+ sethi $p0, hi20(PAGE_OFFSET - PHYS_OFFSET) -+ add $p1, $p1, $p0 -+ -+ /* change to kernel stack */ -+ mfsr $p0, $IPSW -+ andi $p0, $p0, #PSW_mskPOM -+ cmovz $sp, $r25, $p0 -+ -+ /* 8 byte aligned */ -+ movi $r25, #~7 -+ and $r25, $sp, $r25 -+ smw.adm $sp, [$r25], $sp, #0x1 -+ move $sp, $r25 -+ -+#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO) -+ mfsr $r25, $FUCOP_CTL -+ push $r25 -+ bclr $r25, $r25, #FUCOP_CTL_offCP0EN -+ mtsr $r25, $FUCOP_CTL -+#else -+ addi $sp, $sp, -4 -+#endif -+ pushm $r28, $r30 -+ -+ /* zero fp if user mode*/ -+ movi $r25, #0x0 -+ cmovz $fp, $r25, $p0 -+ -+ lwi $r25, [$p1+#0x0] -+ pushm $r0, $r25 -+#ifdef CONFIG_HWZOL -+ push_zol -+#endif -+ mfsr $r9, $P_P1 -+ mfsr $r8, $P_P0 -+ mfsr $r7, $P_IPC -+ mfsr $r6, $P_IPSW -+ mfsr $r18, $IPC -+ mfsr $r17, $IPSW -+ mfsr $r16, $PSW -+ pushm $r6, $r13 -+ push $r0 -+ lwi $p0, [$p1+#0x8] -+ push $p0 -+ pushm $r16, $r18 -+ -+ andi $r19, $r16, #PSW_mskINTL -+ slti $r20, $r19, #4 -+ bnez $r20, 1f -+ addi $r21, $r16, #-2 -+ mtsr $r21, $PSW -+ isb -+1: -+ addi $sp, $sp, -S_OFF -+ .endm -+ -+ .text -+ -+/* -+ * Exception Vector -+ */ -+exception_handlers: -+ .long unhandled_exceptions !Reset/NMI -+ .long unhandled_exceptions !TLB fill -+ .long do_page_fault !PTE not present -+ .long do_dispatch_tlb_misc !TLB misc -+ .long unhandled_exceptions !TLB VLPT -+ .long unhandled_exceptions !Machine Error -+ .long do_debug_trap !Debug related -+ .long do_dispatch_general !General exception -+ .long eh_syscall !Syscall -+ .long asm_do_IRQ !IRQ -+ -+common_exception_handler: -+ save_user_regs -+ lwi $p0, [$p1+#0x4] -+ andi $p1, $p0, #0x78 -+ bnez $p1, 1f -+ sethi $lp, hi20(ret_from_exception) -+ ori $lp, $lp, lo12(ret_from_exception) -+ sethi $p1, hi20(exception_handlers) -+ ori $p1, $p1, lo12(exception_handlers) -+ lw $p1, [$p1+$p0<<2] -+ move $r0, $p0 -+ mfsr $r1, $EVA -+ mfsr $r2, $ITYPE -+ move $r3, $sp -+ mfsr $r4, $OIPC -+ /* enable gie if it is enabled in IPSW. */ -+ mfsr $r21, $PSW -+ andi $r17, $r17, #0x1 -+ or $r21, $r21, $r17 -+ mtsr $r21, $PSW -+ dsb -+ jr $p1 -+ -+ /* syscall */ -+1: -+ addi $p1, $p0, #-8 -+ bnez $p1, 2f -+ sethi $lp, hi20(ret_from_exception) -+ ori $lp, $lp, lo12(ret_from_exception) -+ sethi $p1, hi20(exception_handlers) -+ ori $p1, $p1, lo12(exception_handlers) -+ lwi $p1, [$p1+#0x8<<2] -+ jr $p1 -+ -+ /* interrupt */ -+2: -+#ifdef CONFIG_TRACE_IRQFLAGS -+ jal arch_trace_hardirqs_off -+#endif -+#if defined(CONFIG_EVIC) || defined(CONFIG_IVIC) -+ addi $r0, $p0, #-9 -+#else -+# ifdef CONFIG_IVIC_INTC -+ jal get_IntSrc -+# else -+# error "Not configure Vector Interrupt Controller mode" -+# endif -+#endif -+ move $r1, $sp -+ sethi $lp, hi20(ret_from_intr) -+ ori $lp, $lp, lo12(ret_from_intr) -+ sethi $p0, hi20(exception_handlers) -+ ori $p0, $p0, lo12(exception_handlers) -+ lwi $p0, [$p0+#0x9<<2] -+ jr $p0 -+ -+ .macro EXCEPTION_VECTOR, num -+ .align 6 -+ .ifc \num, 6 -+ mfsr $p0, $EDM_CTL -+ andi $p0, $p0, EDM_CTL_mskV3_EDM_MODE -+ tnez $p0, 0x1a -+ .endif -+ /* $p1 is PA of percpu data */ -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ movi $p1, #0x0 -+#else -+ mfsr $p1, $CORE_ID -+#endif -+ slli $p1, $p1, #0x9 -+ li $p0, #(PHYS_OFFSET+0x6000) -+ or $p1, $p1, $p0 -+ -+ /* -+ * 0x0 saved $r25 -+ * 0x4 vector number -+ * 0x8 user stack pointer -+ * 0xc kernel stack pointer -+ */ -+ swi $r25, [$p1+0x0] -+ movi $p0, \num -+ swi $p0, [$p1+#0x4] -+ swi $sp, [$p1+#0x8] -+ lwi $r25, [$p1+#0xc] -+ sethi $p0, hi20(common_exception_handler) -+ ori $p0, $p0, lo12(common_exception_handler) -+ jral.ton $p0, $p0 -+ .endm -+ -+ .macro IPI_VECTOR, num -+ .align 6 -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ movi $p1, #0x0 -+#else -+ mfsr $p1, $CORE_ID -+#endif -+ slli $p1, $p1, #0x9 -+ li $p0, #(PHYS_OFFSET+0x6000) -+ or $p1, $p1, $p0 -+ -+ /* -+ * 0x10 indicator of CPU is initialized -+ * 0x14 CPU init function -+ */ -+ swi $r25, [$p1+0x0] -+ movi $p0, \num -+ swi $p0, [$p1+#0x4] -+ swi $sp, [$p1+#0x8] -+ lwi $r25, [$p1+#0xc] -+ lwi $p0, [$p1+#0x10] -+ beqz $p0, 1f -+ sethi $p0, hi20(common_exception_handler) -+ ori $p0, $p0, lo12(common_exception_handler) -+ jral.ton $p0, $p0 -+1: -+ lwi $p0, [$p1+#0x14] -+ jr $p0 -+ -+ .endm -+ -+ .section ".text.init", #alloc, #execinstr -+ .global exception_vector -+exception_vector: -+ EXCEPTION_VECTOR 0 -+ EXCEPTION_VECTOR 1 -+ EXCEPTION_VECTOR 2 -+ EXCEPTION_VECTOR 3 -+ EXCEPTION_VECTOR 4 -+ EXCEPTION_VECTOR 5 -+ EXCEPTION_VECTOR 6 -+ EXCEPTION_VECTOR 7 -+ EXCEPTION_VECTOR 8 -+#ifdef CONFIG_EVIC -+ EXCEPTION_VECTOR 9 -+#else -+ IPI_VECTOR 9 -+#endif -+ EXCEPTION_VECTOR 10 -+ EXCEPTION_VECTOR 11 -+ EXCEPTION_VECTOR 12 -+ EXCEPTION_VECTOR 13 -+ EXCEPTION_VECTOR 14 -+ EXCEPTION_VECTOR 15 -+ EXCEPTION_VECTOR 16 -+ EXCEPTION_VECTOR 17 -+ EXCEPTION_VECTOR 18 -+ EXCEPTION_VECTOR 19 -+ EXCEPTION_VECTOR 20 -+ EXCEPTION_VECTOR 21 -+ EXCEPTION_VECTOR 22 -+ EXCEPTION_VECTOR 23 -+ EXCEPTION_VECTOR 24 -+ EXCEPTION_VECTOR 25 -+ EXCEPTION_VECTOR 26 -+ EXCEPTION_VECTOR 27 -+ EXCEPTION_VECTOR 28 -+ EXCEPTION_VECTOR 29 -+ EXCEPTION_VECTOR 30 -+ EXCEPTION_VECTOR 31 -+ EXCEPTION_VECTOR 32 -+ EXCEPTION_VECTOR 33 -+ EXCEPTION_VECTOR 34 -+ EXCEPTION_VECTOR 35 -+ EXCEPTION_VECTOR 36 -+ EXCEPTION_VECTOR 37 -+ EXCEPTION_VECTOR 38 -+ EXCEPTION_VECTOR 39 -+ EXCEPTION_VECTOR 40 -+#ifdef CONFIG_EVIC -+ IPI_VECTOR 41 -+#else -+ EXCEPTION_VECTOR 41 -+#endif -+ EXCEPTION_VECTOR 42 -+ EXCEPTION_VECTOR 43 -+ EXCEPTION_VECTOR 44 -+ EXCEPTION_VECTOR 45 -+ EXCEPTION_VECTOR 46 -+ EXCEPTION_VECTOR 47 -+ EXCEPTION_VECTOR 48 -+ EXCEPTION_VECTOR 49 -+ EXCEPTION_VECTOR 50 -+ EXCEPTION_VECTOR 51 -+ EXCEPTION_VECTOR 52 -+ EXCEPTION_VECTOR 53 -+ EXCEPTION_VECTOR 54 -+ EXCEPTION_VECTOR 55 -+ EXCEPTION_VECTOR 56 -+ EXCEPTION_VECTOR 57 -+ EXCEPTION_VECTOR 58 -+ EXCEPTION_VECTOR 59 -+ EXCEPTION_VECTOR 60 -+ EXCEPTION_VECTOR 61 -+ EXCEPTION_VECTOR 62 -+ EXCEPTION_VECTOR 63 -+ EXCEPTION_VECTOR 64 -+ EXCEPTION_VECTOR 65 -+ EXCEPTION_VECTOR 66 -+ EXCEPTION_VECTOR 67 -+ EXCEPTION_VECTOR 68 -+ EXCEPTION_VECTOR 69 -+ EXCEPTION_VECTOR 70 -+ EXCEPTION_VECTOR 71 -+ EXCEPTION_VECTOR 72 -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/ex-exit.S linux-3.4.113/arch/nds32/kernel/ex-exit.S ---- linux-3.4.113.orig/arch/nds32/kernel/ex-exit.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/ex-exit.S 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,220 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define why $r8 // Linux syscall (!= 0) -+#define tsk $r9 // current thread_info -+ -+ -+ .macro pop_zol -+#ifdef CONFIG_HWZOL -+ mtusr $r10, $LB -+ mtusr $r11, $LE -+ mtusr $r12, $LC -+#endif -+ .endm -+ -+ .macro restore_user_regs_first -+ setgie.d -+ isb -+ /* $p1 is VA of percpu data */ -+#ifdef CONFIG_CPU_N1213_43U1HA0 -+ movi $p1, #0x0 -+#else -+ mfsr $p1, $CORE_ID -+#endif -+ andi $p1, $p1, #0x3 -+ slli $p1, $p1, #0x9 -+ sethi $p0, #0xc0006 -+ or $p1, $p1, $p0 -+ -+ addi $sp, $sp, S_OFF -+ popm $r16, $r18 -+ mtsr $r16, $PSW -+ pop $r16 -+ swi $r16, [$p1+#0x8] -+ addi $sp, $sp, #4 !pop $r0 -+ popm $r6, $r13 -+ mtsr $r17, $IPSW -+ mtsr $r18, $IPC -+ mtsr $r6, $P_IPSW -+ mtsr $r7, $P_IPC -+ mtsr $r8, $P_P0 -+ mtsr $r9, $P_P1 -+#ifdef CONFIG_HWZOL -+ pop_zol -+#endif -+ .endm -+ -+ .macro restore_user_regs_last -+ popm $r28, $r30 -+#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO) -+ pop $p0 -+ mtsr $p0, $FUCOP_CTL -+#else -+ addi $sp, $sp, 4 -+#endif -+ -+ pop $p0 -+ cmovn $sp, $p0, $p0 -+ -+ mfsr $p0, $IPSW -+ andi $p0, $p0, #PSW_mskPOM -+ bnez $p0, 1f -+ swi $sp, [$p1+#0xc] -+ lwi $sp, [$p1+#0x8] -+1: -+ // This is SW workaround for Bug #6294 -+ li $p0, 0xc0000000 -+ cctl $p0, L1D_VA_INVAL -+ lwi $p1, [$p0] -+ -+ iret -+ nop -+ -+ .endm -+ -+ .macro restore_user_regs -+ restore_user_regs_first -+ popm $r0, $r25 -+ restore_user_regs_last -+ .endm -+ -+ .macro fast_restore_user_regs -+ restore_user_regs_first -+ addi $sp, $sp, #4 -+ popm $r1, $r25 -+ restore_user_regs_last -+ .endm -+ -+#ifdef CONFIG_PREEMPT -+ .macro preempt_stop -+ .endm -+#else -+ .macro preempt_stop -+ setgie.d -+ isb -+ .endm -+#define resume_kernel no_work_pending -+#endif -+ -+ENTRY(ret_from_exception) -+ preempt_stop -+ENTRY(ret_from_intr) -+ get_thread_info tsk -+ move why, #0 ! not system call -+ -+/* -+ * judge Kernel or user mode -+ * -+ */ -+ lwi $p0, [$sp+(#S_IPSW+#S_OFF)] -+! mfsr $p0, $IPSW ! Check if in nested interrupt -+ andi $p0, $p0, #PSW_mskINTL -+ bnez $p0, resume_kernel ! done with iret -+ j resume_userspace -+ -+ -+/* -+ * This is the fast syscall return path. We do as little as -+ * possible here, and this includes saving $r0 back into the SVC -+ * stack. -+ * fixed: tsk - $r9, why - $r8, $r7 - syscall #, $r8 - syscall table pointer -+ */ -+ENTRY(ret_fast_syscall) -+ gie_disable -+ lwi $r1, [tsk+#TI_FLAGS] -+ andi $p1, $r1, #_TIF_WORK_MASK -+ bnez $p1, fast_work_pending -+ fast_restore_user_regs ! iret -+ -+/* -+ * Ok, we need to do extra processing, -+ * enter the slow path returning from syscall, while pending work. -+ */ -+fast_work_pending: -+ swi $r0, [$sp+(#S_R0+#S_OFF)] ! what is different from ret_from_exception -+ ! addi $sp, $sp, S_OFF -+ move why, #1 ! come from a syscall -+work_pending: -+ andi $p1, $r1, #_TIF_NEED_RESCHED -+ bnez $p1, work_resched -+ -+ andi $p1, $r1, #_TIF_SIGPENDING|#_TIF_NOTIFY_RESUME -+ beqz $p1, no_work_pending -+ -+ move $r0, $sp ! 'regs' -+ move $r2, why -+ gie_enable -+ bal do_notify_resume -+ -+ b ret_slow_syscall ! return from slow_restore_user_regs -+ -+work_resched: -+ bal schedule ! path, return to user mode -+ -+/* -+ * "slow" syscall return path. -+ * "why" tells us if this was a real syscall. -+ */ -+ENTRY(resume_userspace) -+ENTRY(ret_slow_syscall) -+ gie_disable -+ lwi $p0, [$sp+(#S_IPSW+#S_OFF)] -+! mfsr $p0, $IPSW ! Check if in nested interrupt -+ andi $p0, $p0, #PSW_mskINTL -+ bnez $p0, no_work_pending ! done with iret -+ lwi $r1, [tsk+#TI_FLAGS] -+ andi $p1, $r1, #_TIF_WORK_MASK -+ bnez $p1, work_pending ! handle work_resched, sig_pend -+ -+no_work_pending: -+#ifdef CONFIG_TRACE_IRQFLAGS -+ lwi $p0, [$sp+(#S_IPSW+#S_OFF)] -+ andi $p0, $p0, #0x1 -+ la $r10, arch_trace_hardirqs_off -+ la $r9, arch_trace_hardirqs_on -+ cmovz $r9, $p0, $r10 -+ jral $r9 -+#endif -+ restore_user_regs ! return from iret -+ -+ -+/* -+ * preemptive kernel -+ */ -+#ifdef CONFIG_PREEMPT -+resume_kernel: -+ gie_disable -+ lwi $t0, [tsk+#TI_PREEMPT] -+ bnez $t0, no_work_pending -+need_resched: -+ lwi $t0, [tsk+#TI_FLAGS] -+ andi $p1, $t0, #_TIF_NEED_RESCHED -+ beqz $p1, no_work_pending -+ -+ lwi $t0, [$sp+(#S_IPSW+#S_OFF)] ! Interrupts off? -+ andi $t0, $t0, #1 -+ beqz $t0, no_work_pending -+ -+ jal preempt_schedule_irq -+ b need_resched -+#endif -+ -+/* -+ * This is how we return from a fork. -+ */ -+ENTRY(ret_from_fork) -+ bal schedule_tail -+ get_thread_info tsk -+ lwi $r1, [tsk+#TI_FLAGS] ! check for syscall tracing -+ move why, #1 -+ andi $p1, $r1, #_TIF_WORK_SYSCALL_LEAVE ! are we tracing syscalls? -+ beqz $p1, ret_slow_syscall -+ move $r0, $sp -+ bal syscall_trace_leave -+ b ret_slow_syscall -+ -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/ex-scall.S linux-3.4.113/arch/nds32/kernel/ex-scall.S ---- linux-3.4.113.orig/arch/nds32/kernel/ex-scall.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/ex-scall.S 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,288 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * $r0 = previous task_struct, -+ * $r1 = previous thread_info, -+ * $r2 = next thread_info -+ * previous and next are guaranteed not to be the same. -+ */ -+ -+ENTRY(_switch) -+ smw.adm $r6, [$sp], $r14, #0xa -+ swi $sp, [$r1+ TI_SP_SAVE] /* Save $sp to task structure */ -+ lwi $sp, [$r2+ TI_SP_SAVE] /* Get $sp from task structure */ -+ lmw.bim $r6, [$sp], $r14, #0xa -+ ret -+ -+/* -+ * These are the registers used in the syscall handler, and allow us -+ * to have in theory up to 6 arguments to a function - $r0 to $r5. -+ * $r7 is reserved for the system call number for Andes architecture. -+ * -+ * Note that tbl == why is intentional. -+ * We must set at least "tsk" and "why" when calling ret_with_reschedule. -+ */ -+#define tbl $r8 // syscall table pointer -+#define why $r8 // Linux syscall (!= 0) -+#define tsk $r9 // current thread_info -+ -+/* -+ * Get the system call number. let $r7 take a system call nr. -+ * -+ * if it is called from library function, $r7 is filled by library call -+ * when user program make a system call. and swid bitfield of $ir6 will -+ * always be encoded as 0x7fff. -+ * -+ * if it is called from kernel code, $r7 will be writen as syscall nr -+ * by retrieving from $ir6 'swid' bitfiled -+ */ -+ .macro get_scno -+ mfsr $r7, $ITYPE -+#ifdef CONFIG_PLAT_QEMU -+ slli $r7, $r7, #1 -+ srli $r7, $r7, #ITYPE_offSWID+1 -+#else -+ srli $r7, $r7, #ITYPE_offSWID -+#endif -+ .endm -+ -+ .macro updateipc -+ addi $r17, $r18, #4 -+ swi $r17, [$sp + S_OFF + S_IPC] -+ .endm -+ -+ .equ NR_syscalls,0 -+#define CALL(x) .equ NR_syscalls,NR_syscalls+1 -+#include "calls.S" -+#undef CALL -+#define CALL(x) .long x -+ -+ENTRY(eh_syscall) -+ updateipc -+ -+ get_scno -+ gie_enable -+ get_thread_info tsk -+ lwi $p0, [tsk+#TI_FLAGS] ! check for syscall tracing -+ -+ andi $p1, $p0, #_TIF_WORK_SYSCALL_ENTRY ! are we tracing syscalls? -+ bnez $p1, __sys_trace -+ -+ la $lp, ret_fast_syscall ! return address -+ -+ li $p0, __NR_NDS32_BASE -+ addi $p0, $p0, -1 -+ slt $p0, $p0, $r7 -+ beqz $p0, 1f -+ addi $r1, $SP, #0 -+ move $r0, $r7 -+ b nds32_syscall -+1: -+ ! check upper syscall limit, -+ andi $r7, $r7, #0xfff -+ addi $p1, $r7, #-NR_syscalls ! syscall number of syscall instruction is guarded by addembler -+ bgez $p1, _SCNO_EXCEED ! call sys_* routine -+ la tbl, sys_call_table ! load syscall table pointer -+ slli $p1, $r7, #2 -+ add $p1, tbl, $p1 -+ lwi $p1, [$p1] -+ jr $p1 ! no return -+ -+_SCNO_EXCEED: -+ ori $r0, $r7, #0 -+ ori $r1, $sp, #0 -+ b bad_syscall -+ -+/* -+ * This is the really slow path. We're going to be doing -+ * context switches, and waiting for our parent to respond. -+ */ -+__sys_trace: -+ move $r1, $sp -+ move $r0, $r7 ! trace entry [IP = 0] -+ bal syscall_trace_enter -+ move $r7, $r0 -+ la $lp, __sys_trace_return ! return address -+ -+ li $p0, __NR_NDS32_BASE -+ addi $p0, $p0, -1 -+ slt $p0, $p0, $r7 -+ beqz $p0, 1f -+ addi $r1, $SP, #0 -+ b nds32_syscall -+1: -+ andi $r7, $r7, #0xfff -+ addi $p1, $sp, #S_R0+S_OFF ! pointer to regs -+ addi $p0, $r7, -#NR_syscalls ! check upper syscall limit -+ bgez $p0, _SCNO_EXCEED -+ lmw.bi $r0, [$p1], $r5 ! have to reload $r0 - $r5 -+ -+ slli $p0, $r7, #2 ! call sys_* routine -+ la tbl, sys_call_table ! load syscall table pointer -+ add $p0, tbl, $p0 -+ lwi $p0, [$p0] -+ jr $p0 -+ -+__sys_trace_return: -+ swi $r0, [$sp+(#S_R0+S_OFF)] ! T: save returned $r0 -+ bal syscall_trace_leave -+ b ret_slow_syscall -+ -+ .type sys_call_table, #object -+ENTRY(sys_call_table) -+#include "calls.S" -+ -+/* -+ * Special system call wrappers -+ * -+ * $r0 = syscall number -+ * $r8 = syscall table -+ */ -+ .type sys_syscall, #function -+sys_syscall: -+ -+ li $p0, __NR_NDS32_BASE -+ addi $p0, $p0, -1 -+ slt $p0, $p0, $r0 -+ beqz $p0, 1f -+ addi $r1, $SP, #0 -+ b nds32_syscall -+1: -+ bltz $r0, 3f ! Guard whether syscall number is between 0~0x7fff. -+ andi $r0, $r0, #0xfff -+ addi $p1, $r0, #-NR_syscalls -+ bgtz $p1, 3f -+ move $p1, $r0 -+ move $r0, $r1 -+ move $r1, $r2 -+ move $r2, $r3 -+ move $r3, $r4 -+ move $r4, $r5 -+! add for syscall 6 args -+ lwi $r5, [$sp + (#S_SP + #S_OFF) ] -+ lwi $r5, [$r5 + #S_OFF] -+! ~add for syscall 6 args -+ -+ lw $p1, [tbl+$p1<<2] -+ jr $p1 -+3: b sys_ni_syscall -+ -+sys_fork_wrapper: -+ addi $r0, $sp, #0 -+ b sys_fork -+ -+sys_vfork_wrapper: -+ addi $r0, $sp, #0 -+ b sys_vfork -+ -+sys_execve_wrapper: -+ addi $r3, $sp, #0 -+ b sys_execve -+ -+sys_clone_wrapper: -+ addi $r5, $SP, #0 -+ b sys_clone -+ -+sys_sigsuspend_wrapper: -+ addi $r3, $sp, #0 -+ b sys_sigsuspend -+ -+sys_rt_sigsuspend_wrapper: -+ addi $r2, $sp, #0 -+ b sys_rt_sigsuspend -+ -+sys_sigreturn_wrapper: -+ addi $r0, $sp, #0 -+ b sys_sigreturn -+ -+sys_rt_sigreturn_wrapper: -+ addi $r0, $sp, #0 -+ b sys_rt_sigreturn -+ -+sys_sigaltstack_wrapper: -+ lwi $r2, [$sp+(#S_OFF + S_SP)] -+ b do_sigaltstack -+ -+sys_futex_wrapper: -+ b sys_futex -+ -+#ifdef CONFIG_FUNCTION_TRACER -+ .global _mcount -+ .global ftrace_stub -+_mcount: -+ sethi $r15, hi20(function_trace_stop) -+ lwi $r15, [$r15 + lo12(function_trace_stop)] -+ bnez $r15, _ftrace_stub -+ -+ sethi $r15, hi20(ftrace_trace_function) -+ lwi $p0, [$r15 + lo12(ftrace_trace_function)] -+ sethi $r15, hi20(ftrace_stub) -+ ori $r15, $r15, lo12(ftrace_stub) -+ bne $r15, $p0, trace -+ -+#ifdef CONFIG_FUNCTION_GRAPH_TRACER -+ sethi $p0, hi20(ftrace_graph_return) -+ lwi $p0, [$p0 + lo12(ftrace_graph_return)] -+ bne $r15, $p0, _ftrace_graph_caller -+ -+ sethi $r15, hi20(ftrace_graph_entry) -+ lwi $r15, [$r15 + lo12(ftrace_graph_entry)] -+ sethi $p0, hi20(ftrace_graph_entry_stub) -+ ori $p0, $p0, lo12(ftrace_graph_entry_stub) -+ bne $r15, $p0, _ftrace_graph_caller -+#endif -+ -+_ftrace_stub: -+ftrace_stub: -+ ret -+ -+trace: -+ smw.adm $r0, [$sp], $r5, #10 -+ move $r0, $lp -+ sethi $r15, hi20(get_selfpc) -+ ori $r15, $r15, lo12(get_selfpc) -+ jral $r15 -+ move $r1, $r0 -+ lwi $r0, [$sp+36] -+ jral $p0 -+ lmw.bim $r0, [$sp], $r5, #10 -+ ret -+#endif -+ -+#ifdef CONFIG_FUNCTION_GRAPH_TRACER -+ .global ftrace_graph_caller -+ .global return_to_handler -+_ftrace_graph_caller: -+ftrace_graph_caller: -+ sethi $p1, hi20(function_trace_stop) -+ lwi $p1, [$p1 + lo12(function_trace_stop)] -+ bnez $p1, ftrace_stub -+ -+ sethi $p1, hi20(prepare_ftrace_return) -+ ori $p1, $p1, lo12(prepare_ftrace_return) -+ -+ smw.adm $r0, [$sp], $r5, #10 -+ move $r0, $lp -+ sethi $p0, hi20(get_selfpc) -+ ori $p0, $p0, lo12(get_selfpc) -+ jral $p0 -+ move $r1, $r0 -+ addi $r0, $sp, #36 -+ jral $p1 -+ lmw.bim $r0, [$sp], $r5, #10 -+ ret -+ -+return_to_handler: -+ smw.adm $r0, [$sp], $r5, #10 -+ sethi $r15, hi20(ftrace_return_to_handler) -+ ori $r15, $r15, lo12(ftrace_return_to_handler) -+ jral $r15 -+ move $r15, $r0 -+ lmw.bim $r0, [$sp], $r5, #10 -+ jr $r15 -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/fpu.c linux-3.4.113/arch/nds32/kernel/fpu.c ---- linux-3.4.113.orig/arch/nds32/kernel/fpu.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/fpu.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,306 @@ -+/* -+ * arch/nds32/kernel/fpu.c -+ * -+ * Copyright (C) 2001 Manuela Cirronis, Paolo Alberelli -+ * Copyright (C) 2002 STMicroelectronics Limited -+ * Author : Stuart Menefy -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * Started from SH4 version: -+ * Copyright (C) 1999, 2000 Kaz Kojima & Niibe Yutaka -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "fpu.h" -+ -+extern void do_revinsn(struct pt_regs *regs); -+extern int do_fpu_denorm(struct pt_regs *regs, struct fpu_struct *fpu); -+ -+static struct fpu_struct init_fpuregs = { -+ .fs_regs = {[0 ... 31] = sNAN32}, -+ .fd_regs = {[0 ... 15] = sNAN64}, -+ .fpcsr = FPCSR_INIT -+}; -+ -+void save_fpu(struct task_struct *tsk) -+{ -+ unsigned int fpcfg, fpcsr; -+ enable_fpu(); -+ asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg)); -+ fpcfg = ((fpcfg & FPCFG_mskFREG) >> FPCFG_offFREG); -+ -+ switch (fpcfg) { -+ case 3: -+ asm volatile ("fsdi $fd31, [%0+0xf8]\n\t" -+ "fsdi $fd30, [%0+0xf0]\n\t" -+ "fsdi $fd29, [%0+0xe8]\n\t" -+ "fsdi $fd28, [%0+0xe0]\n\t" -+ "fsdi $fd27, [%0+0xd8]\n\t" -+ "fsdi $fd26, [%0+0xd0]\n\t" -+ "fsdi $fd25, [%0+0xc8]\n\t" -+ "fsdi $fd24, [%0+0xc0]\n\t" -+ "fsdi $fd23, [%0+0xb8]\n\t" -+ "fsdi $fd22, [%0+0xb0]\n\t" -+ "fsdi $fd21, [%0+0xa8]\n\t" -+ "fsdi $fd20, [%0+0xa0]\n\t" -+ "fsdi $fd19, [%0+0x98]\n\t" -+ "fsdi $fd18, [%0+0x90]\n\t" -+ "fsdi $fd17, [%0+0x88]\n\t" -+ "fsdi $fd16, [%0+0x80]\n\t" -+ : /* no output */ -+ :"r" (&tsk->thread.fpu) -+ :"memory"); -+ /* fall through */ -+ case 2: -+ asm volatile ("fssi $fs31, [%0+0x7c]\n\t" -+ "fssi $fs30, [%0+0x78]\n\t" -+ "fssi $fs29, [%0+0x74]\n\t" -+ "fssi $fs28, [%0+0x70]\n\t" -+ "fssi $fs27, [%0+0x6c]\n\t" -+ "fssi $fs26, [%0+0x68]\n\t" -+ "fssi $fs25, [%0+0x64]\n\t" -+ "fssi $fs24, [%0+0x60]\n\t" -+ "fssi $fs23, [%0+0x5c]\n\t" -+ "fssi $fs22, [%0+0x58]\n\t" -+ "fssi $fs21, [%0+0x54]\n\t" -+ "fssi $fs20, [%0+0x50]\n\t" -+ "fssi $fs19, [%0+0x4c]\n\t" -+ "fssi $fs18, [%0+0x48]\n\t" -+ "fssi $fs17, [%0+0x44]\n\t" -+ "fssi $fs16, [%0+0x40]\n\t" -+ : /* no output */ -+ :"r" (&tsk->thread.fpu) -+ :"memory"); -+ /* fall through */ -+ case 1: -+ asm volatile ("fssi $fs15, [%0+0x3c]\n\t" -+ "fssi $fs14, [%0+0x38]\n\t" -+ "fssi $fs13, [%0+0x34]\n\t" -+ "fssi $fs12, [%0+0x30]\n\t" -+ "fssi $fs11, [%0+0x2c]\n\t" -+ "fssi $fs10, [%0+0x28]\n\t" -+ "fssi $fs9, [%0+0x24]\n\t" -+ "fssi $fs8, [%0+0x20]\n\t" -+ : /* no output */ -+ :"r" (&tsk->thread.fpu) -+ :"memory"); -+ /* fall through */ -+ case 0: -+ asm volatile ("fssi $fs7, [%1+0x1c]\n\t" -+ "fssi $fs6, [%1+0x18]\n\t" -+ "fssi $fs5, [%1+0x14]\n\t" -+ "fssi $fs4, [%1+0x10]\n\t" -+ "fssi $fs3, [%1+0xc]\n\t" -+ "fssi $fs2, [%1+0x8]\n\t" -+ "fssi $fs1, [%1+0x4]\n\t" -+ "fssi $fs0, [%1+0x0]\n\t" -+ "fmfcsr %0\n\t" -+ "swi %0, [%1+0x100]\n\t" -+ :"=&r" (fpcsr) -+ :"r"(&tsk->thread.fpu) -+ :"memory"); -+ } -+ disable_fpu(); -+} -+ -+void fpload(struct fpu_struct *fpregs) -+{ -+ unsigned int fpcfg, fpcsr; -+ enable_fpu(); -+ -+ asm volatile ("fmfcfg %0\n\t":"=&r" (fpcfg)); -+ fpcfg = ((fpcfg & FPCFG_mskFREG) >> FPCFG_offFREG); -+ -+ switch (fpcfg) { -+ case 3: -+ asm volatile ("fldi $fd31, [%0+0xf8]\n\t" -+ "fldi $fd30, [%0+0xf0]\n\t" -+ "fldi $fd29, [%0+0xe8]\n\t" -+ "fldi $fd28, [%0+0xe0]\n\t" -+ "fldi $fd27, [%0+0xd8]\n\t" -+ "fldi $fd26, [%0+0xd0]\n\t" -+ "fldi $fd25, [%0+0xc8]\n\t" -+ "fldi $fd24, [%0+0xc0]\n\t" -+ "fldi $fd23, [%0+0xb8]\n\t" -+ "fldi $fd22, [%0+0xb0]\n\t" -+ "fldi $fd21, [%0+0xa8]\n\t" -+ "fldi $fd20, [%0+0xa0]\n\t" -+ "fldi $fd19, [%0+0x98]\n\t" -+ "fldi $fd18, [%0+0x90]\n\t" -+ "fldi $fd17, [%0+0x88]\n\t" -+ "fldi $fd16, [%0+0x80]\n\t" -+ : /* no output */ -+ :"r" (fpregs)); -+ /* fall through */ -+ case 2: -+ asm volatile ("flsi $fs31, [%0+0x7c]\n\t" -+ "flsi $fs30, [%0+0x78]\n\t" -+ "flsi $fs29, [%0+0x74]\n\t" -+ "flsi $fs28, [%0+0x70]\n\t" -+ "flsi $fs27, [%0+0x6c]\n\t" -+ "flsi $fs26, [%0+0x68]\n\t" -+ "flsi $fs25, [%0+0x64]\n\t" -+ "flsi $fs24, [%0+0x60]\n\t" -+ "flsi $fs23, [%0+0x5c]\n\t" -+ "flsi $fs22, [%0+0x58]\n\t" -+ "flsi $fs21, [%0+0x54]\n\t" -+ "flsi $fs20, [%0+0x50]\n\t" -+ "flsi $fs19, [%0+0x4c]\n\t" -+ "flsi $fs18, [%0+0x48]\n\t" -+ "flsi $fs17, [%0+0x44]\n\t" -+ "flsi $fs16, [%0+0x40]\n\t" -+ : /* no output */ -+ :"r" (fpregs)); -+ /* fall through */ -+ case 1: -+ asm volatile ("flsi $fs15, [%0+0x3c]\n\t" -+ "flsi $fs14, [%0+0x38]\n\t" -+ "flsi $fs13, [%0+0x34]\n\t" -+ "flsi $fs12, [%0+0x30]\n\t" -+ "flsi $fs11, [%0+0x2c]\n\t" -+ "flsi $fs10, [%0+0x28]\n\t" -+ "flsi $fs9, [%0+0x24]\n\t" -+ "flsi $fs8, [%0+0x20]\n\t" -+ : /* no output */ -+ :"r" (fpregs)); -+ /* fall through */ -+ case 0: -+ asm volatile ("flsi $fs7, [%1+0x1c]\n\t" -+ "flsi $fs6, [%1+0x18]\n\t" -+ "flsi $fs5, [%1+0x14]\n\t" -+ "flsi $fs4, [%1+0x10]\n\t" -+ "flsi $fs3, [%1+0xc]\n\t" -+ "flsi $fs2, [%1+0x8]\n\t" -+ "flsi $fs1, [%1+0x4]\n\t" -+ "flsi $fs0, [%1+0x0]\n\t" -+ "lwi %0, [%1+0x100]\n\t" -+ "fmtcsr %0\n\t":"=&r" (fpcsr) -+ :"r"(fpregs)); -+ } -+ disable_fpu(); -+} -+ -+void do_fpu_context_switch(unsigned long error_code, struct pt_regs *regs) -+{ -+ /* Enable to use FPU. */ -+ -+ if (!user_mode(regs)) { -+ printk(KERN_ERR "BUG: FPU is used in kernel mode.\n"); -+ BUG(); -+ return; -+ } -+ -+ grab_fpu(regs); -+#ifndef CONFIG_UNLAZY_FPU //Lazy FPU is used -+ if (last_task_used_math == current) -+ return; -+ if (last_task_used_math != NULL) -+ /* Other processes fpu state, save away */ -+ save_fpu(last_task_used_math); -+ last_task_used_math = current; -+#endif -+ if (used_math()) { -+ fpload(¤t->thread.fpu); -+ } else { -+ /* First time FPU user. */ -+ fpload(&init_fpuregs); -+ set_used_math(); -+ } -+ -+} -+ -+void do_fpu_exception(unsigned long error_code, struct pt_regs *regs) -+{ -+ unsigned int subtype = -+ ((GET_ITYPE() & ITYPE_mskSTYPE) >> ITYPE_offSTYPE); -+ unsigned int cpid = ((GET_ITYPE() & ITYPE_mskCPID) >> ITYPE_offCPID); -+ -+ /* FPU */ -+ if ((cpid == 0) && (GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) { -+ /* Coprocessor disabled exception */ -+ if (subtype == 1) { -+ preempt_disable(); -+ do_fpu_context_switch(error_code, regs); -+ preempt_enable(); -+ } -+ /* Coprocessor exception */ -+ else if (subtype == 2) { -+ siginfo_t si = { 0 }; -+ unsigned int fpcsr; -+ enable_fpu(); -+ asm volatile ("fmfcsr %0\n\t":"=&r" (fpcsr)); -+ disable_fpu(); -+ -+ if (fpcsr & FPCSR_mskALLT) { -+ si.si_signo = SIGFPE; -+ /* Exception handling, denorm input, UDF and OVF */ -+ if (fpcsr & FPCSR_mskDNIT) { -+ unsigned int rfpcsr; -+ lose_fpu(1); -+ si.si_signo = -+ do_fpu_denorm(regs, -+ ¤t->thread.fpu); -+ own_fpu(1); -+ -+ if (si.si_signo == SIGFPE) { -+ rfpcsr = -+ current->thread.fpu.fpcsr; -+ -+ if (rfpcsr & FPCSR_mskIVO) -+ si.si_code = FPE_FLTINV; -+ if (rfpcsr & FPCSR_mskDBZ) -+ si.si_code = FPE_FLTDIV; -+ if (rfpcsr & FPCSR_mskOVF) -+ si.si_code = FPE_FLTOVF; -+ if (rfpcsr & FPCSR_mskUDF) -+ si.si_code = FPE_FLTUND; -+ if (rfpcsr & FPCSR_mskIEX) -+ si.si_code = FPE_FLTRES; -+ } else if (si.si_code == SIGILL) -+ show_regs(regs); -+ else if (si.si_code == SIGBUS) -+ si.si_code = BUS_ADRERR; -+ } else if (fpcsr & FPCSR_mskRIT) { -+ printk("Reserved Instruction\n"); -+ show_regs(regs); -+ if (!user_mode(regs)) -+ do_exit(SIGILL); -+ si.si_signo = SIGILL; -+ } else if (fpcsr & FPCSR_mskUDFT) -+ si.si_code = FPE_FLTUND; -+ else if (fpcsr & FPCSR_mskOVFT) -+ si.si_code = FPE_FLTOVF; -+ else if (fpcsr & FPCSR_mskIVOT) -+ si.si_code = FPE_FLTINV; -+ else if (fpcsr & FPCSR_mskDBZT) -+ si.si_code = FPE_FLTDIV; -+ else if (fpcsr & FPCSR_mskIEXT) -+ si.si_code = FPE_FLTRES; -+ /* If something went wrong, signal */ -+ if (si.si_signo) { -+ if (si.si_code == SIGILL) { -+ force_sig(si.si_signo, current); -+ } else { -+ si.si_addr = -+ (void __user *) -+ instruction_pointer(regs); -+ force_sig_info(si.si_signo, &si, -+ current); -+ } -+ } -+ } else { -+ printk("Bad FPU exception\n"); -+ BUG(); -+ } -+ } -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/fpu.h linux-3.4.113/arch/nds32/kernel/fpu.h ---- linux-3.4.113.orig/arch/nds32/kernel/fpu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/fpu.h 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,13 @@ -+ -+ -+/* -+ * Initially load the FPU with signalling NANS. This bit pattern -+ * has the property that no matter whether considered as single or as -+ * double precision, it still represents a signalling NAN. -+ */ -+ -+ #define sNAN64 0xFFFFFFFFFFFFFFFFULL -+ #define sNAN32 0xFFFFFFFFUL -+ -+ #define FPCSR_INIT 0x0 /* Hardware reset value */ -+ -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/ftrace.c linux-3.4.113/arch/nds32/kernel/ftrace.c ---- linux-3.4.113.orig/arch/nds32/kernel/ftrace.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/ftrace.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,219 @@ -+/* -+ * Code for replacing ftrace calls with jumps. -+ * -+ * Copyright (C) 2007-2008 Steven Rostedt -+ * -+ * Thanks goes out to P.A. Semi, Inc for supplying me with a PPC64 box. -+ * -+ * Added function graph tracer code, taken from x86 that was written -+ * by Frederic Weisbecker, and ported to PPC by Steven Rostedt. -+ * -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+# define GET_ADDR(addr) (*(unsigned long *)addr) -+ -+#ifdef CONFIG_DYNAMIC_FTRACE -+static unsigned int ftrace_nop_replace(void) -+{ -+// return PPC_INST_NOP; -+ return 0; -+} -+ -+static unsigned int -+ftrace_call_replace(unsigned long ip, unsigned long addr, int link) -+{ -+ unsigned int op; -+ -+ addr = GET_ADDR(addr); -+ -+ /* if (link) set op to 'bl' else 'b' */ -+// op = create_branch((unsigned int *)ip, addr, link ? 1 : 0); -+ -+ return op; -+} -+ -+static int -+ftrace_modify_code(unsigned long ip, unsigned int old, unsigned int new) -+{ -+ unsigned int replaced; -+ -+ /* -+ * Note: Due to modules and __init, code can -+ * disappear and change, we need to protect against faulting -+ * as well as code changing. We do this by using the -+ * probe_kernel_* functions. -+ * -+ * No real locking needed, this code is run through -+ * kstop_machine, or before SMP starts. -+ */ -+ -+ /* read the text we want to modify */ -+ if (probe_kernel_read(&replaced, (void *)ip, MCOUNT_INSN_SIZE)) -+ return -EFAULT; -+ -+ /* Make sure it is what we expect it to be */ -+ if (replaced != old) -+ return -EINVAL; -+ -+ /* replace the text with the new text */ -+ if (probe_kernel_write((void *)ip, &new, MCOUNT_INSN_SIZE)) -+ return -EPERM; -+ -+ flush_icache_range(ip, ip + 8); -+ -+ return 0; -+} -+ -+int ftrace_make_nop(struct module *mod, -+ struct dyn_ftrace *rec, unsigned long addr) -+{ -+ unsigned long ip = rec->ip; -+ unsigned int old, new; -+ -+ old = ftrace_call_replace(ip, addr, 1); -+ new = ftrace_nop_replace(); -+ return ftrace_modify_code(ip, old, new); -+} -+ -+int ftrace_make_call(struct dyn_ftrace *rec, unsigned long addr) -+{ -+ unsigned long ip = rec->ip; -+ unsigned int old, new; -+ -+ old = ftrace_nop_replace(); -+ new = ftrace_call_replace(ip, addr, 1); -+ return ftrace_modify_code(ip, old, new); -+} -+ -+int ftrace_update_ftrace_func(ftrace_func_t func) -+{ -+ unsigned long ip = (unsigned long)(&ftrace_call); -+ unsigned int old, new; -+ int ret; -+ -+ old = *(unsigned int *)&ftrace_call; -+ new = ftrace_call_replace(ip, (unsigned long)func, 1); -+ ret = ftrace_modify_code(ip, old, new); -+ -+ return ret; -+} -+ -+int __init ftrace_dyn_arch_init(void *data) -+{ -+ /* caller expects data to be zero */ -+ unsigned long *p = data; -+ -+ *p = 0; -+ -+ return 0; -+} -+#endif /* CONFIG_DYNAMIC_FTRACE */ -+ -+#ifdef CONFIG_FUNCTION_GRAPH_TRACER -+ -+#ifdef CONFIG_DYNAMIC_FTRACE -+extern void ftrace_graph_call(void); -+extern void ftrace_graph_stub(void); -+ -+int ftrace_enable_ftrace_graph_caller(void) -+{ -+ unsigned long ip = (unsigned long)(&ftrace_graph_call); -+ unsigned long addr = (unsigned long)(&ftrace_graph_caller); -+ unsigned long stub = (unsigned long)(&ftrace_graph_stub); -+ unsigned int old, new; -+ -+ old = ftrace_call_replace(ip, stub, 0); -+ new = ftrace_call_replace(ip, addr, 0); -+ -+ return ftrace_modify_code(ip, old, new); -+} -+ -+int ftrace_disable_ftrace_graph_caller(void) -+{ -+ unsigned long ip = (unsigned long)(&ftrace_graph_call); -+ unsigned long addr = (unsigned long)(&ftrace_graph_caller); -+ unsigned long stub = (unsigned long)(&ftrace_graph_stub); -+ unsigned int old, new; -+ -+ old = ftrace_call_replace(ip, addr, 0); -+ new = ftrace_call_replace(ip, stub, 0); -+ -+ return ftrace_modify_code(ip, old, new); -+} -+#endif /* CONFIG_DYNAMIC_FTRACE */ -+int get_selfpc(unsigned long mcount_lp) -+{ -+ unsigned long symbol_size, offset; -+ kallsyms_lookup_size_offset(mcount_lp, &symbol_size, &offset); -+ return mcount_lp - offset; -+} -+ -+/* -+ * Hook the return address and push it in the stack of return addrs -+ * in current thread info. -+ */ -+void prepare_ftrace_return(unsigned long *parent, unsigned long self_addr) -+{ -+ unsigned long old; -+ int faulted; -+ struct ftrace_graph_ent trace; -+ unsigned long return_hooker = (unsigned long)&return_to_handler; -+ -+ if (unlikely(atomic_read(¤t->tracing_graph_pause))) -+ return; -+ -+ /* -+ * Protect against fault, even if it shouldn't -+ * happen. This tool is too much intrusive to -+ * ignore such a protection. -+ */ -+ asm volatile ("1: lwi %[old], [%[parent]]\n" -+ "2: swi %[return_hooker], [%[parent]]\n" -+ " movi %[faulted], 0\n" -+ "3:\n" -+ ".section .fixup, \"ax\"\n" -+ ".align 2 \n" -+ "4: movi %[faulted], 1\n" -+ " b 3b\n" -+ ".previous\n" -+ ".section __ex_table,\"a\"\n" -+ ".align 3 \n" -+ ".long 1b,4b\n" -+ ".long 2b,4b\n" -+ ".previous":[old] "=&r"(old),[faulted] "=r"(faulted) -+ :[parent] "r"(parent),[return_hooker] "r"(return_hooker) -+ :"memory"); -+ -+ if (unlikely(faulted)) { -+ ftrace_graph_stop(); -+ WARN_ON(1); -+ return; -+ } -+ -+ trace.func = self_addr; -+ trace.depth = current->curr_ret_stack + 1; -+ -+ /* Only trace if the calling function expects to */ -+ if (!ftrace_graph_entry(&trace)) { -+ *parent = old; -+ return; -+ } -+ -+ if (ftrace_push_return_trace(old, self_addr, &trace.depth, 0) == -EBUSY) { -+ *parent = old; -+ return; -+ } -+} -+#endif /* CONFIG_FUNCTION_GRAPH_TRACER */ -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/head.S linux-3.4.113/arch/nds32/kernel/head.S ---- linux-3.4.113.orig/arch/nds32/kernel/head.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/head.S 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,350 @@ -+/* -+ * arch/nds32/kernel/head.S -+ * -+ * NDS32 Kernel startup code -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+//#include -+#include -+#include -+#include -+#include -+ -+/* -+ * We place the page tables 16K below TEXTADDR. Therefore, we must make sure -+ * that TEXTADDR is correctly set. Currently, we expect the least significant -+ * 16 bits to be 0x8000, but we could probably relax this restriction to -+ * TEXTADDR >= PAGE_OFFSET + 0x4000 -+ * -+ * Note that swapper_pg_dir is the virtual address of the page tables, and -+ * pgtbl gives us a position-independent reference to these tables. We can -+ * do this because _stext == TEXTADDR -+ */ -+ -+ .globl swapper_pg_dir -+ .equ swapper_pg_dir, TEXTADDR - 0x4000 -+ -+/* -+ * Kernel startup entry point. -+ * --------------------------- -+ * -+ * This is normally called from the decompressor code. The requirements -+ * are: MMU = off, D-cache = off, I-cache = dont care, $r0 = 0, -+ * $r1 = machine nr. -+ * -+ * This code is mostly position independent, so if you link the kernel at -+ * 0xc0008000, you call this at __pa(0xc0008000). -+ * -+ * See linux/arch/nds32/tools/mach-types for the complete list of machine -+ * numbers for $r1. -+ * -+ * We're trying to keep crap to a minimum; DO NOT add any machine specific -+ * crap here - that's what the boot loader (or in extreme, well justified -+ * circumstances, zImage) is for. -+ */ -+ .section ".head.text", "ax" -+ .type _stext, %function -+ENTRY(_stext) -+ setgie.d ! Disable interrupt -+ isb -+ move $r1, #MACH_TYPE_FARADAY ! Note: as far, we are in the Superuser mode -+ jal __lookup_processor_type ! get processor id, $r5=procinfo, $r9=cpuid, invalid processor $r5=0 -+ li $r2, 'p' -+ beqz $r5, __error ! yes, error 'p' -+ jal __lookup_machine_type ! $r5=machinfo -+ li $r2, 'a' -+ beqz $r5, __error -+ -+/* -+ * Create a temporary mapping area for booting, before start_kernel -+ */ -+ sethi $r4, hi20(swapper_pg_dir) -+ li $p0, (PAGE_OFFSET - PHYS_OFFSET) -+ sub $r4, $r4, $p0 -+ tlbop FlushAll ! invalidate TLB\n" -+ isb -+ mtsr $r4, $L1_PPTB ! load page table pointer\n" -+ -+/* set NTC0 cacheable/writeback, mutliple page size in use */ -+ mfsr $r3, $MMU_CTL -+ li $r0, ~0x6 -+ and $r3, $r3, $r0 -+ ori $r3, $r3, 0x404 -+ mtsr $r3, $MMU_CTL -+ isb -+ -+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -+ li $r2, #(PHYS_OFFSET + 0x7bf) -+#else -+ li $r2, #(PHYS_OFFSET + 0x6bf) ! to remember here -+#endif -+ movi $r3, #0x5 -+ mtsr $r3, $TLB_MISC -+ -+ sethi $r3, hi20(PAGE_OFFSET) -+ li $r0, #PHYS_OFFSET -+ sethi $r5, hi20(SZ_1M) ! Use 1MB pages -+ sethi $r6, hi20(PHYS_OFFSET+SZ_32M) ! Create 32MB first, leave the rest in paging_init() -+_tlb: -+ mtsr $r3, $TLB_VPN -+ dsb -+ tlbop $r2, RWR -+ isb -+ add $r0, $r0, $r5 -+ add $r3, $r3, $r5 -+ add $r2, $r2, $r5 -+ bne $r0, $r6, _tlb -+ -+ mtsr $r3, $TLB_MISC ! setup access page size -+ li $r2, #~0xf -+ and $r3, $r3, $r2 -+#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -+ ori $r3, $r3, #0x1 -+#endif -+ mtsr $r3, $TLB_MISC -+ -+ mfsr $r0, $MISC_CTL ! Enable BTB and RTP -+ li $r1, #~0x3 -+ and $r0, $r0, $r1 -+ mtsr $r0, $MISC_CTL -+ -+/* -+ * Disable L2CC and wait until L2CC registers are mapped into memory to use L2$. -+ */ -+#ifdef CONFIG_CACHE_L2 -+ li $p0, L2CC_PA_BASE -+ li $p1, 0 -+ swi $p1, [$p0 + L2CC_CTRL_OFF] -+#endif -+ -+#ifdef CONFIG_PLAT_AG102 -+/* -+ * Set GPUBA to 0x0c000006. GPUB 0x1c000000, FB size 64MB. -+ */ -+ li $p0, DDR2C_PA_BASE + 0x02a4 -+ li $p1, 0x0c000006 -+ swi $p1, [$p0] -+#endif -+ -+ mfsr $p1, $PSW -+ li $r15, #~0x43df ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE -+ and $p1, $p1, $r15 -+#ifdef __NDS32_EB__ -+ #ifdef CONFIG_WBNA -+ ori $p1, $p1, #0x40ea ! set WBNA|DT|IT|BE|POM:super|INTL:1 -+ #else -+ ori $p1, $p1, #0xea ! set ----|DT|IT|BE|POM:super|INTL:1 -+ #endif -+#else -+ #ifdef CONFIG_WBNA -+ ori $p1, $p1, #0x40ca ! set WBNA|DT|IT|--|POM:super|INTL:1 -+ #else -+ ori $p1, $p1, #0xca ! set ----|DT|IT|--|POM:super|INTL:1 -+ #endif -+#endif -+ -+ mtsr $p1, $IPSW ! when iret, it will automatically enable MMU -+ la $lp, __mmap_switched -+ mtsr $lp, $IPC -+ iret -+ nop -+ -+ .type __switch_data, %object -+__switch_data: -+ .long __mmap_switched -+ .long _sdata ! $r5 -+ .long __bss_start ! $r6 -+ .long _end ! $r7 -+ .long __machine_arch_type ! $r5 -+ .long init_thread_union + 8192 ! $sp -+ -+ -+/* -+ * The following fragment of code is executed with the MMU on in MMU mode, -+ * and uses absolute addresses; this is not position independent. -+ * -+ * $r0 -+ * $r10 = points to proc info -+ * $r8 = points to machine info, -+ * $r1 = machine ID, 0x2c8 for Andes AG101 board -+ * $r9 = processor ID of value in version register -+ */ -+ .align -+ .type __mmap_switched, %function -+__mmap_switched: -+ la $r3, __switch_data + 4 -+ lmw.bim $r5, [$r3], $r7 -+ -+ move $fp, #0 ! Clear BSS (and zero $fp) -+ beq $r7, $r6, _RRT -+1: swi.bi $fp, [$r6], #4 -+ bne $r7, $r6, 1b -+ -+_RRT: -+ lmw.bim $r4, [$r3], $r4, #0b0001 -+ sw $r1, [$r4] ! Save machine type to memory -+ b start_kernel -+ -+ -+/* -+ * Read processor ID register (CP#15, $CR0), and look up in the linker-built -+ * supported processor list. Note that we can't use the absolute addresses -+ * for the __proc_info lists since we aren't running with the MMU on -+ * (and therefore, we are not in the correct address space). We have to -+ * calculate the offset. -+ * -+ * $r9 = cpuid, get from $CPU_VER -+ * Returns: -+ * $r3, $r4, $r6 corrupted -+ * $r5 = proc_info pointer in physical address space -+ * $r9 = cpuid -+ */ -+ -+ .type __lookup_processor_type, %function -+__lookup_processor_type: -+ la $r5, __proc_info_begin -+ la $r6, __proc_info_end -+ mfsr $r9, $CPU_VER ! get cpu version -+ li $p0, (PAGE_OFFSET - PHYS_OFFSET) -+1: -+ sub $p1, $r5, $p0 -+ lmw.bi $r3, [$p1], $r4 ! value, mask -+ and $r4, $r4, $r9 ! mask wanted bits -+ xor $p1, $r3, $r4 -+ beqz $p1, 2f -+ addi $r5, $r5, #PROC_INFO_SZ ! sizeof(proc_info_list) -+ bne $r5, $r6, 1b -+ -+ move $r5, #0 ! unknown processor -> exit -+2: ret -+ -+ -+ -+/* -+ * Lookup machine architecture in the linker-build list of architectures. -+ * Note that we can't use the absolute addresses for the __arch_info -+ * lists since we aren't running with the MMU on (and therefore, we are -+ * not in the correct address space). We have to calculate the offset. -+ * -+ * $r1 = machine architecture number -+ * Returns: -+ * $r3, $r4, $r6 corrupted -+ * $r5 = mach_info pointer in physical address space -+ */ -+ .type __lookup_machine_type, %function -+__lookup_machine_type: -+ la $r5, __arch_info_begin -+ la $r6, __arch_info_end -+1: -+ li $p0, (PAGE_OFFSET - PHYS_OFFSET) -+ sub $p1, $r5, $p0 -+ lwi $r3, [$p1] ! use PA to get machine type -+ xor $p1, $r3, $r1 ! matches loader number? -+ beqz $p1, 2f ! found -+ addi $r5, $r5, #SIZEOF_MACHINE_DESC ! next machine_desc -+ bne $r5, $r6, 1b -+ move $r5, #0 ! unknown machine -+2: ret -+ -+ -+/* -+ * Exception handling. Something went wrong and we can't proceed. We -+ * ought to tell the user, but since we don't have any guarantee that -+ * we're even running on the right architecture, we do virtually nothing. -+ * -+ * a = invalid architecture -+ * p = invalid processor -+ * -+ * Generally, only serious errors cause this. -+ */ -+__error: -+ li $r1, UART0_PA_BASE -+ sw $r2, [$r1] -+die: b die -+ -+ -+ -+#ifdef CONFIG_SMP -+ -+ .type secondary_startup, %function -+ENTRY(secondary_startup) -+ /* -+ * Common entry point for secondary CPUs. -+ * -+ * Lookup the processor type - there is no need to check the -+ * machine type as it has already been validated by the -+ * primary processor. -+ */ -+ mfsr $r0, $MMU_CTL -+ ori $r0, $r0, #4 -+#ifndef CONFIG_NO_KERNEL_LARGE_PAGE -+ ori $r0, $r0, #0x400 -+#endif -+ mtsr $r0, $MMU_CTL -+ -+ movi $r15, #0x01 -+ swi $r15, [$p1+#0x10] -+ lwi $sp, [$p1+#0x18] -+ -+ /* -+ * Set stack, L1_PPTB, and enable mmu -+ */ -+ sethi $r4, hi20(swapper_pg_dir) -+ li $p0, (PAGE_OFFSET - PHYS_OFFSET) -+ sub $r4, $r4, $p0 -+ -+ tlbop FlushAll -+ isb -+ mtsr $r4, $L1_PPTB -+ -+#ifdef CONFIG_CACHE_L2 -+ li $r0, #0x1801 -+ mtsr $r0, $HSMP_SADDR -+ isb -+ li $r0, #(L2CC_PA_BASE+0x10) ! L2CC Control -+ lwi $r1, [$r0] -+ li $r2, #~(0xf << 28) -+ and $r1, $r1, $r2 -+ bset $r1, $r1, #29 -+ bset $r1, $r1, #31 -+ swi $r1, [$r0] -+#endif -+ -+ move $fp, #0 -+ -+ mfsr $p1, $PSW -+ li $r15, #~0x43df ! clear WBNA|DME|IME|DT|IT|POM|INTL|GIE -+ and $p1, $p1, $r15 -+#ifdef __NDS32_EB__ -+ #ifdef CONFIG_WBNA -+ ori $p1, $p1, #0x40ea ! set WBNA|DT|IT|BE|POM:super|INTL:1 -+ #else -+ ori $p1, $p1, #0xea ! set ----|DT|IT|BE|POM:super|INTL:1 -+ #endif -+#else -+ #ifdef CONFIG_WBNA -+ ori $p1, $p1, #0x40ca ! set WBNA|DT|IT|--|POM:super|INTL:1 -+ #else -+ ori $p1, $p1, #0xca ! set ----|DT|IT|--|POM:super|INTL:1 -+ #endif -+#endif -+ -+ mtsr $p1, $IPSW ! when iret, it will automatically enable MMU -+ la $lp, secondary_start_kernel -+ mtsr $lp, $IPC -+ iret -+ nop -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/init_task.c linux-3.4.113/arch/nds32/kernel/init_task.c ---- linux-3.4.113.orig/arch/nds32/kernel/init_task.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/init_task.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,25 @@ -+/* -+ * linux/arch/nds32/kernel/init_task.c -+ * -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+ -+static struct signal_struct init_signals = INIT_SIGNALS(init_signals); -+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand); -+ -+/* Initial task structure */ -+struct task_struct init_task = INIT_TASK(init_task); -+EXPORT_SYMBOL(init_task); -+ -+/* -+ * Initial thread structure. Alignment of this is handled by a special -+ * linker map entry. -+ */ -+union thread_union init_thread_union __init_task_data = -+ { INIT_THREAD_INFO(init_task) }; -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/io.c linux-3.4.113/arch/nds32/kernel/io.c ---- linux-3.4.113.orig/arch/nds32/kernel/io.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/io.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,51 @@ -+#include -+#include -+ -+#include -+ -+/* -+ * Copy data from IO memory space to "real" memory space. -+ * This needs to be optimized. -+ */ -+void _memcpy_fromio(void *to, const volatile void __iomem * from, size_t count) -+{ -+ unsigned char *t = to; -+ while (count) { -+ count--; -+ *t = readb(from); -+ t++; -+ from++; -+ } -+} -+ -+/* -+ * Copy data from "real" memory space to IO memory space. -+ * This needs to be optimized. -+ */ -+void _memcpy_toio(volatile void __iomem * to, const void *from, size_t count) -+{ -+ const unsigned char *f = from; -+ while (count) { -+ count--; -+ writeb(*f, to); -+ f++; -+ to++; -+ } -+} -+ -+/* -+ * "memset" on IO memory space. -+ * This needs to be optimized. -+ */ -+void _memset_io(volatile void __iomem * dst, int c, size_t count) -+{ -+ while (count) { -+ count--; -+ writeb(c, dst); -+ dst++; -+ } -+} -+ -+EXPORT_SYMBOL(_memcpy_fromio); -+EXPORT_SYMBOL(_memcpy_toio); -+EXPORT_SYMBOL(_memset_io); -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/irq.c linux-3.4.113/arch/nds32/kernel/irq.c ---- linux-3.4.113.orig/arch/nds32/kernel/irq.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/irq.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,122 @@ -+/* -+ * linux/arch/nds32/kernel/irq.c -+ * -+ * Copyright (C) 1992 Linus Torvalds -+ * Modifications for ARM processor Copyright (C) 1995-2000 Russell King. -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * This file contains the code used by various IRQ handling routines: -+ * asking for different IRQ's should be done through these routines -+ * instead of just grabbing them. Thus setups with different IRQ numbers -+ * shouldn't result in any weird surprises, and installing new handlers -+ * should be easier. -+ * -+ * IRQ's are in fact implemented a bit like signal handlers for the kernel. -+ * Naturally it's not a 1:1 relation, but there are similarities. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+void (*init_arch_irq) (void)__initdata = NULL; -+unsigned long irq_err_count; -+ -+void ack_bad_irq(unsigned int irq) -+{ -+ printk("bad IRQ %d\n", irq); -+} -+ -+int show_interrupts(struct seq_file *p, void *v) -+{ -+ int i = *(loff_t *) v, cpu; -+ struct irqaction *action; -+ unsigned long flags; -+ -+ if (i == 0) { -+ char cpuname[12]; -+ -+ seq_printf(p, " "); -+ for_each_present_cpu(cpu) { -+ sprintf(cpuname, "CPU%d", cpu); -+ seq_printf(p, " %10s", cpuname); -+ } -+ seq_putc(p, '\n'); -+ } -+ -+ if (i < NR_IRQS) { -+ raw_spin_lock_irqsave(&irq_desc[i].lock, flags); -+ action = irq_desc[i].action; -+ if (!action) -+ goto unlock; -+ -+ seq_printf(p, "%3d: ", i); -+ for_each_present_cpu(cpu) -+ seq_printf(p, "%10u ", kstat_irqs_cpu(i, cpu)); -+ seq_printf(p, " %s", action->name); -+ for (action = action->next; action; action = action->next) -+ seq_printf(p, ", %s", action->name); -+ -+ seq_putc(p, '\n'); -+unlock: -+ raw_spin_unlock_irqrestore(&irq_desc[i].lock, flags); -+ } else if (i == NR_IRQS) { -+ seq_printf(p, "Err: %10lu\n", irq_err_count); -+ } -+ return 0; -+} -+ -+/* -+ * do_IRQ handles all hardware IRQ's. Decoded IRQs should not -+ * come via this function. Instead, they should provide their -+ * own 'handler' -+ */ -+asmlinkage void asm_do_IRQ(unsigned int irq, struct pt_regs *regs) -+{ -+ struct pt_regs *old_regs = set_irq_regs(regs); -+ -+ /* -+ * Some hardware gives randomly wrong interrupts. Rather -+ * than crashing, do something sensible. -+ */ -+ if (unlikely(irq >= NR_IRQS)) { -+ printk(KERN_EMERG "IRQ exceeds NR_IRQS\n"); -+ BUG(); -+ } -+ -+ irq_enter(); -+ generic_handle_irq(irq); -+ irq_exit(); -+ set_irq_regs(old_regs); -+ -+} -+ -+void __init init_IRQ(void) -+{ -+ int irq; -+ -+ for (irq = 0; irq < NR_IRQS; irq++) -+ irq_set_noprobe(irq); -+ -+ init_arch_irq(); -+} -+ -+#ifdef CONFIG_TRACE_IRQFLAGS -+void notrace arch_trace_hardirqs_on(void) -+{ -+ trace_hardirqs_on(); -+} -+ -+void notrace arch_trace_hardirqs_off(void) -+{ -+ trace_hardirqs_off(); -+} -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/kgdb.c linux-3.4.113/arch/nds32/kernel/kgdb.c ---- linux-3.4.113.orig/arch/nds32/kernel/kgdb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/kgdb.c 2016-12-01 20:59:24.352612751 +0100 -@@ -0,0 +1,291 @@ -+/* ============================================================================ -+ * -+ * arch/nds32/kernel/kgdb.c -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for NDS32 KGDB support. -+ * -+ * Author: Harry Pan -+ * -+ * Revision History: -+ * -+ * Nov.23.2007 Initial ported by Harry, -+ * inherited from the KGDB in 2.6.11 and 2.4.35. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+// ============================================================================ -+// regs_to_gdb_regs() -+// -+// Make a local copy of the registers passed into the handler (bletch). -+// ============================================================================ -+void pt_regs_to_gdb_regs(unsigned long *gregs, struct pt_regs *kregs) -+{ -+ int regno; -+ -+ /* Initialize all to zero (??) */ -+ for (regno = 0; regno < NDS32_NUM_REGS; regno++) -+ gregs[regno] = 0; -+ -+ gregs[0] = kregs->NDS32_r0; -+ gregs[1] = kregs->NDS32_r1; -+ gregs[2] = kregs->NDS32_r2; -+ gregs[3] = kregs->NDS32_r3; -+ gregs[4] = kregs->NDS32_r4; -+ gregs[5] = kregs->NDS32_r5; -+ gregs[6] = kregs->NDS32_r6; -+ gregs[7] = kregs->NDS32_r7; -+ gregs[8] = kregs->NDS32_r8; -+ gregs[9] = kregs->NDS32_r9; -+ gregs[10] = kregs->NDS32_r10; -+ gregs[11] = kregs->NDS32_r11; -+ gregs[12] = kregs->NDS32_r12; -+ gregs[13] = kregs->NDS32_r13; -+ gregs[14] = kregs->NDS32_r14; -+ gregs[15] = kregs->NDS32_r15; -+ gregs[16] = kregs->NDS32_r16; -+ gregs[17] = kregs->NDS32_r17; -+ gregs[18] = kregs->NDS32_r18; -+ gregs[19] = kregs->NDS32_r19; -+ gregs[20] = kregs->NDS32_r20; -+ gregs[21] = kregs->NDS32_r21; -+ gregs[22] = kregs->NDS32_r22; -+ gregs[23] = kregs->NDS32_r23; -+ gregs[24] = kregs->NDS32_r24; -+ gregs[25] = kregs->NDS32_r25; -+ gregs[26] = kregs->NDS32_pp0; -+ gregs[27] = kregs->NDS32_pp1; -+ gregs[28] = kregs->NDS32_fp; -+ gregs[29] = kregs->NDS32_gp; -+ gregs[30] = kregs->NDS32_lp; -+ gregs[31] = kregs->NDS32_sp; -+ gregs[32] = kregs->NDS32_ipc; -+ gregs[33] = kregs->NDS32_d0lo; -+ gregs[34] = kregs->NDS32_d0hi; -+ gregs[35] = kregs->NDS32_d1lo; -+ gregs[36] = kregs->NDS32_d1hi; -+ gregs[NDS32_IR0_REGNUM] = kregs->NDS32_ipsw; -+} -+ -+// ============================================================================ -+// gdb_regs_to_regs() -+// -+// Copy local gdb registers back to kgdb regs, for later copy to kernel. -+// ============================================================================ -+void gdb_regs_to_pt_regs(unsigned long *gregs, struct pt_regs *kregs) -+{ -+ kregs->NDS32_r0 = gregs[0]; -+ kregs->NDS32_r1 = gregs[1]; -+ kregs->NDS32_r2 = gregs[2]; -+ kregs->NDS32_r3 = gregs[3]; -+ kregs->NDS32_r4 = gregs[4]; -+ kregs->NDS32_r5 = gregs[5]; -+ kregs->NDS32_r6 = gregs[6]; -+ kregs->NDS32_r7 = gregs[7]; -+ kregs->NDS32_r8 = gregs[8]; -+ kregs->NDS32_r9 = gregs[9]; -+ kregs->NDS32_r10 = gregs[10]; -+ kregs->NDS32_r11 = gregs[11]; -+ kregs->NDS32_r12 = gregs[12]; -+ kregs->NDS32_r13 = gregs[13]; -+ kregs->NDS32_r14 = gregs[14]; -+ kregs->NDS32_r15 = gregs[15]; -+ kregs->NDS32_r16 = gregs[16]; -+ kregs->NDS32_r17 = gregs[17]; -+ kregs->NDS32_r18 = gregs[18]; -+ kregs->NDS32_r19 = gregs[19]; -+ kregs->NDS32_r20 = gregs[20]; -+ kregs->NDS32_r21 = gregs[21]; -+ kregs->NDS32_r22 = gregs[22]; -+ kregs->NDS32_r23 = gregs[23]; -+ kregs->NDS32_r24 = gregs[24]; -+ kregs->NDS32_r25 = gregs[25]; -+ kregs->NDS32_pp0 = gregs[26]; -+ kregs->NDS32_pp1 = gregs[27]; -+ kregs->NDS32_fp = gregs[28]; -+ kregs->NDS32_gp = gregs[29]; -+ kregs->NDS32_lp = gregs[30]; -+ kregs->NDS32_sp = gregs[31]; -+ kregs->NDS32_ipc = gregs[32]; -+ kregs->NDS32_d0lo = gregs[33]; -+ kregs->NDS32_d0hi = gregs[34]; -+ kregs->NDS32_d1lo = gregs[35]; -+ kregs->NDS32_d1hi = gregs[36]; -+ kregs->NDS32_ipsw = gregs[NDS32_IR0_REGNUM]; -+} -+ -+// ---------------------------------------------------------------------------- -+// kgdb_get_user_regs() -+// -+// Get user process registers. -+// ---------------------------------------------------------------------------- -+static inline struct pt_regs *kgdb_get_user_regs(struct task_struct *task) -+{ -+ return (struct pt_regs *) -+ ((unsigned long)task_thread_info(task) + THREAD_SIZE - -+ 8 - sizeof(struct pt_regs)); -+} -+ -+// ============================================================================ -+// sleeping_thread_to_gdb_regs() -+// -+// ============================================================================ -+void sleeping_thread_to_gdb_regs(unsigned long *gregs, struct task_struct *task) -+{ -+ int regno; -+ struct pt_regs *tregs; -+ -+ /* Just making sure... */ -+ if (task == NULL) -+ return; -+ -+ /* Initialize to zero */ -+ for (regno = 0; regno < NDS32_NUM_REGS; regno++) -+ gregs[regno] = 0; -+ -+ /* Otherwise, we have only some registers from switch_to() */ -+ tregs = kgdb_get_user_regs(task); -+ -+ gregs[0] = tregs->NDS32_r0; -+ gregs[1] = tregs->NDS32_r1; -+ gregs[2] = tregs->NDS32_r2; -+ gregs[3] = tregs->NDS32_r3; -+ gregs[4] = tregs->NDS32_r4; -+ gregs[5] = tregs->NDS32_r5; -+ gregs[6] = tregs->NDS32_r6; -+ gregs[7] = tregs->NDS32_r7; -+ gregs[8] = tregs->NDS32_r8; -+ gregs[9] = tregs->NDS32_r9; -+ gregs[10] = tregs->NDS32_r10; -+ gregs[11] = tregs->NDS32_r11; -+ gregs[12] = tregs->NDS32_r12; -+ gregs[13] = tregs->NDS32_r13; -+ gregs[14] = tregs->NDS32_r14; -+ gregs[15] = tregs->NDS32_r15; -+ gregs[16] = tregs->NDS32_r16; -+ gregs[17] = tregs->NDS32_r17; -+ gregs[18] = tregs->NDS32_r18; -+ gregs[19] = tregs->NDS32_r19; -+ gregs[20] = tregs->NDS32_r20; -+ gregs[21] = tregs->NDS32_r21; -+ gregs[22] = tregs->NDS32_r22; -+ gregs[23] = tregs->NDS32_r23; -+ gregs[24] = tregs->NDS32_r24; -+ gregs[25] = tregs->NDS32_r25; -+ gregs[26] = tregs->NDS32_pp0; -+ gregs[27] = tregs->NDS32_pp1; -+ gregs[28] = tregs->NDS32_fp; -+ gregs[29] = tregs->NDS32_gp; -+ gregs[30] = tregs->NDS32_lp; -+ gregs[31] = tregs->NDS32_sp; -+ gregs[32] = tregs->NDS32_ipc; -+ gregs[33] = tregs->NDS32_d0lo; -+ gregs[34] = tregs->NDS32_d0hi; -+ gregs[35] = tregs->NDS32_d1lo; -+ gregs[36] = tregs->NDS32_d1hi; -+ gregs[NDS32_IR0_REGNUM] = tregs->NDS32_ipsw; -+} -+ -+int kgdb_arch_handle_exception(int exception_vector, int signo, -+ int err_code, char *remcom_in_buffer, -+ char *remcom_out_buffer, -+ struct pt_regs *linux_regs) -+{ -+ long addr; -+ char *ptr; -+ -+ if (0 == atomic_dec_if_positive(&kgdb_setting_breakpoint)) -+ linux_regs->NDS32_ipc += 2; -+ -+ switch (remcom_in_buffer[0]) { -+ case 'k': -+ case 'D': -+ case 'c': -+ case 's': -+ kgdb_contthread = NULL; -+ -+ /* -+ * Try to read optional parameter, pc unchanged if no parm. -+ * If this was a compiled breakpoint, we need to move -+ * to the next instruction or we will just breakpoint -+ * over and over again. -+ */ -+ ptr = &remcom_in_buffer[1]; -+ if (kgdb_hex2long(&ptr, &addr)) { -+ linux_regs->NDS32_ipc = addr; -+ } -+ linux_regs->NDS32_ipsw &= ~0x800; -+ if (remcom_in_buffer[0] == 's') { -+ linux_regs->NDS32_ipsw |= 0x800; -+ } -+ -+ return 0; -+ } -+ -+ return -1; -+} -+ -+static int kgdb_notify(struct notifier_block *self, -+ unsigned long cmd, void *ptr) -+{ -+ struct die_args *args = ptr; -+ unsigned long addr = args->err; -+ if (addr > TASK_SIZE) { -+ kgdb_handle_exception(args->trapnr, args->signr, -+ args->err, args->regs); -+ return NOTIFY_STOP; -+ } -+ return NOTIFY_DONE; -+} -+ -+static struct notifier_block kgdb_notifier = { -+ .notifier_call = kgdb_notify, -+}; -+ -+int kgdb_arch_init(void) -+{ -+ register_die_notifier(&kgdb_notifier); -+} -+ -+void kgdb_arch_exit(void) -+{ -+ unregister_die_notifier(&kgdb_notifier); -+} -+ -+struct kgdb_arch arch_kgdb_ops = { -+#ifdef __NDS32_EL__ -+ .gdb_bpt_instr = {0xeb, 0xff} -+#else -+ .gdb_bpt_instr = {0xff, 0xeb} -+#endif -+}; -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/kprobes.c linux-3.4.113/arch/nds32/kernel/kprobes.c ---- linux-3.4.113.orig/arch/nds32/kernel/kprobes.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/kprobes.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,869 @@ -+/* -+ * Kernel Probes (KProbes) -+ * -+ * 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. -+ * -+ * Copyright (C) IBM Corporation, 2002, 2004 -+ * -+ * 2002-Oct Created by Vamsi Krishna S Kernel -+ * Probes initial implementation ( includes contributions from -+ * Rusty Russell). -+ * 2004-July Suparna Bhattacharya added jumper probes -+ * interface to access function arguments. -+ * 2004-Oct Jim Keniston and Prasanna S Panchamukhi -+ * adapted for x86_64 from i386. -+ * 2005-Mar Roland McGrath -+ * Fixed to handle %rip-relative addressing mode correctly. -+ * 2005-May Hien Nguyen , Jim Keniston -+ * and Prasanna S Panchamukhi -+ * added function-return probes. -+ * 2005-May Rusty Lynch -+ * Added function return probes functionality -+ * 2006-Feb Masami Hiramatsu added -+ * kprobe-booster and kretprobe-booster for i386. -+ * 2007-Dec Masami Hiramatsu added kprobe-booster -+ * and kretprobe-booster for x86-64 -+ * 2007-Dec Masami Hiramatsu , Arjan van de Ven -+ * and Jim Keniston -+ * unified x86 kprobes code. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#ifdef __NDS32_EL__ -+#define SZINSN(insn) (((insn & 0x00000080) == 0) ? 4 : 2) -+#define BREAK16_1FE 0xFEEB -+#else -+#define SZINSN(insn) (((insn & 0x80000000) == 0) ? 4 : 2) -+#define BREAK16_1FE 0xEBFE -+#endif -+ -+void jprobe_return_point(void); -+ -+DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; -+DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); -+ -+#if 0 -+/* Insert a jump instruction at address 'from', which jumps to address 'to'.*/ -+static void __kprobes set_jmp_op(void *from, void *to) -+{ -+ struct __arch_jmp_op { -+ char op; -+ s32 raddr; -+ } __attribute__ ((packed)) * jop; -+ jop = (struct __arch_jmp_op *)from; -+ jop->raddr = (s32) ((long)(to) - ((long)(from) + 5)); -+ jop->op = RELATIVEJUMP_INSTRUCTION; -+} -+ -+/* -+ * Check for the REX prefix which can only exist on X86_64 -+ * X86_32 always returns 0 -+ */ -+static int __kprobes is_REX_prefix(kprobe_opcode_t * insn) -+{ -+#ifdef CONFIG_X86_64 -+ if ((*insn & 0xf0) == 0x40) -+ return 1; -+#endif -+ return 0; -+} -+ -+/* -+ * Returns non-zero if opcode is boostable. -+ * RIP relative instructions are adjusted at copying time in 64 bits mode -+ */ -+static int __kprobes can_boost(kprobe_opcode_t * opcodes) -+{ -+ kprobe_opcode_t opcode; -+ kprobe_opcode_t *orig_opcodes = opcodes; -+ -+ if (search_exception_tables(opcodes)) -+ return 0; /* Page fault may occur on this address. */ -+ -+retry: -+ if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) -+ return 0; -+ opcode = *(opcodes++); -+ -+ /* 2nd-byte opcode */ -+ if (opcode == 0x0f) { -+ if (opcodes - orig_opcodes > MAX_INSN_SIZE - 1) -+ return 0; -+ return test_bit(*opcodes, -+ (unsigned long *)twobyte_is_boostable); -+ } -+ -+ switch (opcode & 0xf0) { -+#ifdef CONFIG_X86_64 -+ case 0x40: -+ goto retry; /* REX prefix is boostable */ -+#endif -+ case 0x60: -+ if (0x63 < opcode && opcode < 0x67) -+ goto retry; /* prefixes */ -+ /* can't boost Address-size override and bound */ -+ return (opcode != 0x62 && opcode != 0x67); -+ case 0x70: -+ return 0; /* can't boost conditional jump */ -+ case 0xc0: -+ /* can't boost software-interruptions */ -+ return (0xc1 < opcode && opcode < 0xcc) || opcode == 0xcf; -+ case 0xd0: -+ /* can boost AA* and XLAT */ -+ return (opcode == 0xd4 || opcode == 0xd5 || opcode == 0xd7); -+ case 0xe0: -+ /* can boost in/out and absolute jmps */ -+ return ((opcode & 0x04) || opcode == 0xea); -+ case 0xf0: -+ if ((opcode & 0x0c) == 0 && opcode != 0xf1) -+ goto retry; /* lock/rep(ne) prefix */ -+ /* clear and set flags are boostable */ -+ return (opcode == 0xf5 || (0xf7 < opcode && opcode < 0xfe)); -+ default: -+ /* segment override prefixes are boostable */ -+ if (opcode == 0x26 || opcode == 0x36 || opcode == 0x3e) -+ goto retry; /* prefixes */ -+ /* CS override prefix and call are not boostable */ -+ return (opcode != 0x2e && opcode != 0x9a); -+ } -+} -+ -+/* -+ * Returns non-zero if opcode modifies the interrupt flag. -+ */ -+static int __kprobes is_IF_modifier(kprobe_opcode_t * insn) -+{ -+ switch (*insn) { -+ case 0xfa: /* cli */ -+ case 0xfb: /* sti */ -+ case 0xcf: /* iret/iretd */ -+ case 0x9d: /* popf/popfd */ -+ return 1; -+ } -+ -+ /* -+ * on X86_64, 0x40-0x4f are REX prefixes so we need to look -+ * at the next byte instead.. but of course not recurse infinitely -+ */ -+ if (is_REX_prefix(insn)) -+ return is_IF_modifier(++insn); -+ -+ return 0; -+} -+ -+/* -+ * Adjust the displacement if the instruction uses the %rip-relative -+ * addressing mode. -+ * If it does, Return the address of the 32-bit displacement word. -+ * If not, return null. -+ * Only applicable to 64-bit x86. -+ */ -+static void __kprobes fix_riprel(struct kprobe *p) -+{ -+#ifdef CONFIG_X86_64 -+ u8 *insn = p->ainsn.insn; -+ s64 disp; -+ int need_modrm; -+ -+ /* Skip legacy instruction prefixes. */ -+ while (1) { -+ switch (*insn) { -+ case 0x66: -+ case 0x67: -+ case 0x2e: -+ case 0x3e: -+ case 0x26: -+ case 0x64: -+ case 0x65: -+ case 0x36: -+ case 0xf0: -+ case 0xf3: -+ case 0xf2: -+ ++insn; -+ continue; -+ } -+ break; -+ } -+ -+ /* Skip REX instruction prefix. */ -+ if (is_REX_prefix(insn)) -+ ++insn; -+ -+ if (*insn == 0x0f) { -+ /* Two-byte opcode. */ -+ ++insn; -+ need_modrm = test_bit(*insn, -+ (unsigned long *)twobyte_has_modrm); -+ } else -+ /* One-byte opcode. */ -+ need_modrm = test_bit(*insn, -+ (unsigned long *)onebyte_has_modrm); -+ -+ if (need_modrm) { -+ u8 modrm = *++insn; -+ if ((modrm & 0xc7) == 0x05) { -+ /* %rip+disp32 addressing mode */ -+ /* Displacement follows ModRM byte. */ -+ ++insn; -+ /* -+ * The copied instruction uses the %rip-relative -+ * addressing mode. Adjust the displacement for the -+ * difference between the original location of this -+ * instruction and the location of the copy that will -+ * actually be run. The tricky bit here is making sure -+ * that the sign extension happens correctly in this -+ * calculation, since we need a signed 32-bit result to -+ * be sign-extended to 64 bits when it's added to the -+ * %rip value and yield the same 64-bit result that the -+ * sign-extension of the original signed 32-bit -+ * displacement would have given. -+ */ -+ disp = (u8 *) p->addr + *((s32 *) insn) - -+ (u8 *) p->ainsn.insn; -+ BUG_ON((s64) (s32) disp != disp); /* Sanity check. */ -+ *(s32 *) insn = (s32) disp; -+ } -+ } -+#endif -+} -+#endif -+ -+static void __kprobes arch_copy_kprobe(struct kprobe *p) -+{ -+ memcpy(p->ainsn.insn, p->addr, MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); -+ flush_icache_range((unsigned long)p->ainsn.insn, -+ (unsigned long)p->ainsn.insn + -+ MAX_INSN_SIZE * sizeof(kprobe_opcode_t)); -+ -+// fix_riprel(p); -+ -+// if (can_boost(p->addr)) -+// p->ainsn.boostable = 0; -+// else -+ p->ainsn.boostable = -1; -+ -+ p->opcode = *p->addr; -+} -+ -+int __kprobes arch_prepare_kprobe(struct kprobe *p) -+{ -+ /* insn: must be on special executable page on x86. */ -+ p->ainsn.insn = get_insn_slot(); -+ if (!p->ainsn.insn) -+ return -ENOMEM; -+ arch_copy_kprobe(p); -+ return 0; -+} -+ -+void __kprobes arch_arm_kprobe(struct kprobe *p) -+{ -+ *p->addr = BREAK16_1FE; -+ flush_icache_range((unsigned long)p->addr, -+ (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -+} -+ -+void __kprobes arch_disarm_kprobe(struct kprobe *p) -+{ -+ *p->addr = p->opcode; -+ flush_icache_range((unsigned long)p->addr, -+ (unsigned long)p->addr + sizeof(kprobe_opcode_t)); -+} -+ -+void __kprobes arch_remove_kprobe(struct kprobe *p) -+{ -+ if (p->ainsn.insn) { -+ free_insn_slot(p->ainsn.insn, (p->ainsn.boostable == 1)); -+ p->ainsn.insn = NULL; -+ } -+} -+ -+static void __kprobes save_previous_kprobe(struct kprobe_ctlblk *kcb) -+{ -+ kcb->prev_kprobe.kp = kprobe_running(); -+ kcb->prev_kprobe.status = kcb->kprobe_status; -+ kcb->prev_kprobe.old_flags = kcb->kprobe_old_flags; -+ kcb->prev_kprobe.saved_flags = kcb->kprobe_saved_flags; -+} -+ -+static void __kprobes restore_previous_kprobe(struct kprobe_ctlblk *kcb) -+{ -+ __get_cpu_var(current_kprobe) = kcb->prev_kprobe.kp; -+ kcb->kprobe_status = kcb->prev_kprobe.status; -+ kcb->kprobe_old_flags = kcb->prev_kprobe.old_flags; -+ kcb->kprobe_saved_flags = kcb->prev_kprobe.saved_flags; -+} -+ -+static void __kprobes set_current_kprobe(struct kprobe *p, struct pt_regs *regs, -+ struct kprobe_ctlblk *kcb) -+{ -+ __get_cpu_var(current_kprobe) = p; -+// kcb->kprobe_saved_flags = kcb->kprobe_old_flags -+// = regs->NDS32_ipsw & PSW_mskHSS; -+} -+ -+static void __kprobes prepare_singlestep(struct kprobe *p, struct pt_regs *regs) -+{ -+ regs->NDS32_ipsw |= PSW_mskHSS; -+ /* single step inline if the instruction is an int3 */ -+// if (p->opcode == BREAK16_1FE) -+// regs->NDS32_ipc = (unsigned long)p->addr; -+// else -+ regs->NDS32_ipc = (unsigned long)p->ainsn.insn; -+} -+ -+void __kprobes arch_prepare_kretprobe(struct kretprobe_instance *ri, -+ struct pt_regs *regs) -+{ -+ ri->ret_addr = (kprobe_opcode_t *) regs->NDS32_lp; -+ regs->NDS32_lp = (unsigned long)&kretprobe_trampoline; -+} -+ -+static void __kprobes setup_singlestep(struct kprobe *p, struct pt_regs *regs, -+ struct kprobe_ctlblk *kcb) -+{ -+#if !defined(CONFIG_PREEMPT) || defined(CONFIG_FREEZER) -+ if (p->ainsn.boostable == 1 && !p->post_handler) { -+ /* Boost up -- we can execute copied instructions directly */ -+ reset_current_kprobe(); -+ regs->NDS32_ipc = (unsigned long)p->ainsn.insn; -+ preempt_enable_no_resched(); -+ return; -+ } -+#endif -+ prepare_singlestep(p, regs); -+ kcb->kprobe_status = KPROBE_HIT_SS; -+} -+ -+/* -+ * We have reentered the kprobe_handler(), since another probe was hit while -+ * within the handler. We save the original kprobes variables and just single -+ * step on the instruction of the new probe without calling any user handlers. -+ */ -+static int __kprobes reenter_kprobe(struct kprobe *p, struct pt_regs *regs, -+ struct kprobe_ctlblk *kcb) -+{ -+ switch (kcb->kprobe_status) { -+#if 0 -+ case KPROBE_HIT_SSDONE: -+#ifdef CONFIG_X86_64 -+ /* TODO: Provide re-entrancy from post_kprobes_handler() and -+ * avoid exception stack corruption while single-stepping on -+ * the instruction of the new probe. -+ */ -+ arch_disarm_kprobe(p); -+ regs->ip = (unsigned long)p->addr; -+ reset_current_kprobe(); -+ preempt_enable_no_resched(); -+ break; -+#endif -+#endif -+ case KPROBE_HIT_ACTIVE: -+ save_previous_kprobe(kcb); -+ set_current_kprobe(p, regs, kcb); -+ kprobes_inc_nmissed_count(p); -+ prepare_singlestep(p, regs); -+ kcb->kprobe_status = KPROBE_REENTER; -+ break; -+ case KPROBE_HIT_SS: -+ if (p == kprobe_running()) { -+ regs->NDS32_ipc &= ~PSW_mskHSS; -+// regs->NDS32_ipc |= kcb->kprobe_saved_flags; -+ return 0; -+ } else { -+ /* A probe has been hit in the codepath leading up -+ * to, or just after, single-stepping of a probed -+ * instruction. This entire codepath should strictly -+ * reside in .kprobes.text section. Raise a warning -+ * to highlight this peculiar case. -+ */ -+ } -+ default: -+ /* impossible cases */ -+ WARN_ON(1); -+ return 0; -+ } -+ -+ return 1; -+} -+ -+/* -+ * Interrupts are disabled on entry as trap3 is an interrupt gate and they -+ * remain disabled thorough out this function. -+ */ -+static int __kprobes kprobe_handler(struct pt_regs *regs) -+{ -+ kprobe_opcode_t *addr; -+ struct kprobe *p; -+ struct kprobe_ctlblk *kcb; -+ -+ addr = (kprobe_opcode_t *) regs->NDS32_ipc; -+ if (*addr != BREAK16_1FE) { -+ /* -+ * The breakpoint instruction was removed right -+ * after we hit it. Another cpu has removed -+ * either a probepoint or a debugger breakpoint -+ * at this address. In either case, no further -+ * handling of this interrupt is appropriate. -+ * Back up over the (now missing) int3 and run -+ * the original instruction. -+ */ -+ return 1; -+ } -+ -+ /* -+ * We don't want to be preempted for the entire -+ * duration of kprobe processing. We conditionally -+ * re-enable preemption at the end of this function, -+ * and also in reenter_kprobe() and setup_singlestep(). -+ */ -+ preempt_disable(); -+ -+ kcb = get_kprobe_ctlblk(); -+ p = get_kprobe(addr); -+ -+ if (p) { -+ if (kprobe_running()) { -+ if (reenter_kprobe(p, regs, kcb)) -+ return 1; -+ } else { -+ set_current_kprobe(p, regs, kcb); -+ kcb->kprobe_status = KPROBE_HIT_ACTIVE; -+ -+ /* -+ * If we have no pre-handler or it returned 0, we -+ * continue with normal processing. If we have a -+ * pre-handler and it returned non-zero, it prepped -+ * for calling the break_handler below on re-entry -+ * for jprobe processing, so get out doing nothing -+ * more here. -+ */ -+ if (!p->pre_handler || !p->pre_handler(p, regs)) -+ setup_singlestep(p, regs, kcb); -+ return 1; -+ } -+ } else if (kprobe_running()) { -+ p = __get_cpu_var(current_kprobe); -+ if (p->break_handler && p->break_handler(p, regs)) { -+ setup_singlestep(p, regs, kcb); -+ return 1; -+ } -+ } -+ /* else: not a kprobe fault; let the kernel handle it */ -+ preempt_enable_no_resched(); -+ return 0; -+} -+ -+/* -+ * When a retprobed function returns, this code saves registers and -+ * calls trampoline_handler() runs, which calls the kretprobe's handler. -+ */ -+static void __used __kprobes kretprobe_trampoline_holder(void) -+{ -+ asm volatile (".global kretprobe_trampoline \n" -+ "kretprobe_trampoline: \n" -+ "smw.adm $r15, [$sp], $r15, #0x0\n" -+ "smw.adm $r0, [$sp], $r5, #0x1 \n" -+ "addi $r0, $sp, #-76 \n" -+ "bal trampoline_handler \n" -+ "move $lp, $r0 \n" -+ "lmw.bim $r0, [$sp], $r5, #0x1 \n" -+ "lmw.bim $r15, [$sp], $r15, #0x0\n" -+ "ret \n"); -+} -+ -+/* -+ * Called from kretprobe_trampoline -+ */ -+static __used __kprobes void *trampoline_handler(struct pt_regs *regs) -+{ -+ struct kretprobe_instance *ri = NULL; -+ struct hlist_head *head, empty_rp; -+ struct hlist_node *node, *tmp; -+ unsigned long flags, orig_ret_address = 0; -+ unsigned long trampoline_address = (unsigned long)&kretprobe_trampoline; -+ -+ INIT_HLIST_HEAD(&empty_rp); -+ kretprobe_hash_lock(current, &head, &flags); -+ -+ /* -+ * It is possible to have multiple instances associated with a given -+ * task either because multiple functions in the call path have -+ * return probes installed on them, and/or more than one -+ * return probe was registered for a target function. -+ * -+ * We can handle this because: -+ * - instances are always pushed into the head of the list -+ * - when multiple return probes are registered for the same -+ * function, the (chronologically) first instance's ret_addr -+ * will be the real return address, and all the rest will -+ * point to kretprobe_trampoline. -+ */ -+ hlist_for_each_entry_safe(ri, node, tmp, head, hlist) { -+ if (ri->task != current) -+ /* another task is sharing our hash bucket */ -+ continue; -+ -+ if (ri->rp && ri->rp->handler) { -+ __get_cpu_var(current_kprobe) = &ri->rp->kp; -+ get_kprobe_ctlblk()->kprobe_status = KPROBE_HIT_ACTIVE; -+ ri->rp->handler(ri, regs); -+ __get_cpu_var(current_kprobe) = NULL; -+ } -+ -+ orig_ret_address = (unsigned long)ri->ret_addr; -+ recycle_rp_inst(ri, &empty_rp); -+ -+ if (orig_ret_address != trampoline_address) -+ /* -+ * This is the real return address. Any other -+ * instances associated with this task are for -+ * other calls deeper on the call stack -+ */ -+ break; -+ } -+ -+ kretprobe_assert(ri, orig_ret_address, trampoline_address); -+ -+ kretprobe_hash_unlock(current, &flags); -+ -+ hlist_for_each_entry_safe(ri, node, tmp, &empty_rp, hlist) { -+ hlist_del(&ri->hlist); -+ kfree(ri); -+ } -+ return (void *)orig_ret_address; -+} -+ -+/* -+ * Called after single-stepping. p->addr is the address of the -+ * instruction whose first byte has been replaced by the "int 3" -+ * instruction. To avoid the SMP problems that can occur when we -+ * temporarily put back the original opcode to single-step, we -+ * single-stepped a copy of the instruction. The address of this -+ * copy is p->ainsn.insn. -+ * -+ * This function prepares to return from the post-single-step -+ * interrupt. We have to fix up the stack as follows: -+ * -+ * 0) Except in the case of absolute or indirect jump or call instructions, -+ * the new ip is relative to the copied instruction. We need to make -+ * it relative to the original instruction. -+ * -+ * 1) If the single-stepped instruction was pushfl, then the TF and IF -+ * flags are set in the just-pushed flags, and may need to be cleared. -+ * -+ * 2) If the single-stepped instruction was a call, the return address -+ * that is atop the stack is the address following the copied instruction. -+ * We need to make it the address following the original instruction. -+ * -+ * If this is the first time we've single-stepped the instruction at -+ * this probepoint, and the instruction is boostable, boost it: add a -+ * jump instruction after the copied instruction, that jumps to the next -+ * instruction after the probepoint. -+ */ -+static void __kprobes resume_execution(struct kprobe *p, -+ struct pt_regs *regs, -+ struct kprobe_ctlblk *kcb) -+{ -+// unsigned long *tos = stack_addr(regs); -+// unsigned long copy_ip = (unsigned long)p->ainsn.insn; -+// unsigned long orig_ip = (unsigned long)p->addr; -+ kprobe_opcode_t *insn = p->ainsn.insn; -+ unsigned long rawinsn = *(unsigned long *)insn; -+ int size = SZINSN(rawinsn); -+ regs->NDS32_ipc = (unsigned long)p->addr + size; -+ regs->NDS32_ipsw &= ~PSW_mskHSS; -+#if 0 -+ -+ /*skip the REX prefix */ -+ if (is_REX_prefix(insn)) -+ insn++; -+ -+ regs->flags &= ~X86_EFLAGS_TF; -+ switch (*insn) { -+ case 0x9c: /* pushfl */ -+ *tos &= ~(X86_EFLAGS_TF | X86_EFLAGS_IF); -+ *tos |= kcb->kprobe_old_flags; -+ break; -+ case 0xc2: /* iret/ret/lret */ -+ case 0xc3: -+ case 0xca: -+ case 0xcb: -+ case 0xcf: -+ case 0xea: /* jmp absolute -- ip is correct */ -+ /* ip is already adjusted, no more changes required */ -+ p->ainsn.boostable = 1; -+ goto no_change; -+ case 0xe8: /* call relative - Fix return addr */ -+ *tos = orig_ip + (*tos - copy_ip); -+ break; -+#ifdef CONFIG_X86_32 -+ case 0x9a: /* call absolute -- same as call absolute, indirect */ -+ *tos = orig_ip + (*tos - copy_ip); -+ goto no_change; -+#endif -+ case 0xff: -+ if ((insn[1] & 0x30) == 0x10) { -+ /* -+ * call absolute, indirect -+ * Fix return addr; ip is correct. -+ * But this is not boostable -+ */ -+ *tos = orig_ip + (*tos - copy_ip); -+ goto no_change; -+ } else if (((insn[1] & 0x31) == 0x20) || -+ ((insn[1] & 0x31) == 0x21)) { -+ /* -+ * jmp near and far, absolute indirect -+ * ip is correct. And this is boostable -+ */ -+ p->ainsn.boostable = 1; -+ goto no_change; -+ } -+ default: -+ break; -+ } -+ -+ if (p->ainsn.boostable == 0) { -+ if ((regs->ip > copy_ip) && -+ (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) { -+ /* -+ * These instructions can be executed directly if it -+ * jumps back to correct address. -+ */ -+ set_jmp_op((void *)regs->ip, -+ (void *)orig_ip + (regs->ip - copy_ip)); -+ p->ainsn.boostable = 1; -+ } else { -+ p->ainsn.boostable = -1; -+ } -+ } -+ -+ regs->ip += orig_ip - copy_ip; -+ -+no_change: -+ restore_btf(); -+#endif -+} -+ -+/* -+ * Interrupts are disabled on entry as trap1 is an interrupt gate and they -+ * remain disabled thoroughout this function. -+ */ -+static int __kprobes post_kprobe_handler(struct pt_regs *regs) -+{ -+ struct kprobe *cur = kprobe_running(); -+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); -+ -+ if (!cur) -+ return 0; -+ -+ resume_execution(cur, regs, kcb); -+ regs->NDS32_ipsw |= kcb->kprobe_saved_flags; -+ -+ if ((kcb->kprobe_status != KPROBE_REENTER) && cur->post_handler) { -+ kcb->kprobe_status = KPROBE_HIT_SSDONE; -+ cur->post_handler(cur, regs, 0); -+ } -+ -+ /* Restore back the original saved kprobes variables and continue. */ -+ if (kcb->kprobe_status == KPROBE_REENTER) { -+ restore_previous_kprobe(kcb); -+ goto out; -+ } -+ reset_current_kprobe(); -+out: -+ preempt_enable_no_resched(); -+ -+ /* -+ * if somebody else is singlestepping across a probe point, flags -+ * will have TF set, in which case, continue the remaining processing -+ * of do_debug, as if this is not a probe hit. -+ */ -+ if (regs->NDS32_ipsw & PSW_mskHSS) -+ return 0; -+ -+ return 1; -+} -+ -+int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) -+{ -+ struct kprobe *cur = kprobe_running(); -+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); -+ -+ switch (kcb->kprobe_status) { -+ case KPROBE_HIT_SS: -+ case KPROBE_REENTER: -+ /* -+ * We are here because the instruction being single -+ * stepped caused a page fault. We reset the current -+ * kprobe and the ip points back to the probe address -+ * and allow the page fault handler to continue as a -+ * normal page fault. -+ */ -+ regs->NDS32_ipc = (unsigned long)cur->addr; -+ regs->NDS32_ipsw |= kcb->kprobe_old_flags; -+ if (kcb->kprobe_status == KPROBE_REENTER) -+ restore_previous_kprobe(kcb); -+ else -+ reset_current_kprobe(); -+ preempt_enable_no_resched(); -+ break; -+ case KPROBE_HIT_ACTIVE: -+ case KPROBE_HIT_SSDONE: -+ /* -+ * We increment the nmissed count for accounting, -+ * we can also use npre/npostfault count for accounting -+ * these specific fault cases. -+ */ -+ kprobes_inc_nmissed_count(cur); -+ -+ /* -+ * We come here because instructions in the pre/post -+ * handler caused the page_fault, this could happen -+ * if handler tries to access user space by -+ * copy_from_user(), get_user() etc. Let the -+ * user-specified handler try to fix it first. -+ */ -+ if (cur->fault_handler && cur->fault_handler(cur, regs, trapnr)) -+ return 1; -+ -+ /* -+ * In case the user-specified fault handler returned -+ * zero, try to fix up. -+ */ -+ if (fixup_exception(regs)) -+ return 1; -+ -+ /* -+ * fixup routine could not handle it, -+ * Let do_page_fault() fix it. -+ */ -+ break; -+ default: -+ break; -+ } -+ return 0; -+} -+ -+/* -+ * Wrapper routine for handling exceptions. -+ */ -+int __kprobes kprobe_exceptions_notify(struct notifier_block *self, -+ unsigned long val, void *data) -+{ -+ struct die_args *args = data; -+ int ret = NOTIFY_DONE; -+ int why = args->trapnr & 0xf; -+ -+ if (args->regs && user_mode(args->regs)) -+ return ret; -+ -+ switch (why) { -+ case 1: -+ if (kprobe_handler(args->regs)) -+ ret = NOTIFY_STOP; -+ break; -+ case 7: -+ if (post_kprobe_handler(args->regs)) -+ ret = NOTIFY_STOP; -+ break; -+ default: -+ break; -+ } -+ return ret; -+} -+ -+int __kprobes setjmp_pre_handler(struct kprobe *p, struct pt_regs *regs) -+{ -+ struct jprobe *jp = container_of(p, struct jprobe, kp); -+ unsigned long addr; -+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); -+ -+ kcb->jprobe_saved_regs = *regs; -+ kcb->jprobe_saved_sp = regs->NDS32_sp; -+ addr = (unsigned long)(kcb->jprobe_saved_sp); -+ -+ /* -+ * As Linus pointed out, gcc assumes that the callee -+ * owns the argument space and could overwrite it, e.g. -+ * tailcall optimization. So, to be absolutely safe -+ * we also save and restore enough stack bytes to cover -+ * the argument area. -+ */ -+ memcpy(kcb->jprobes_stack, (kprobe_opcode_t *) addr, -+ MIN_STACK_SIZE(addr)); -+ regs->NDS32_ipsw &= ~PSW_mskGIE; -+ trace_hardirqs_off(); -+ regs->NDS32_ipc = (unsigned long)(jp->entry); -+ return 1; -+} -+ -+void __kprobes jprobe_return(void) -+{ -+ struct kprobe_ctlblk *kcd = get_kprobe_ctlblk(); -+ asm volatile (" move $sp, %0\n" -+ " .globl jprobe_return_point\n" -+ " jprobe_return_point: \n" -+ " break #0x1fe \n"::"r" (kcd-> -+ jprobe_saved_sp)); -+} -+ -+int __kprobes longjmp_break_handler(struct kprobe *p, struct pt_regs *regs) -+{ -+ struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); -+ struct jprobe *jp = container_of(p, struct jprobe, kp); -+ -+ if (regs->NDS32_ipc == jprobe_return_point) { -+ if (regs->NDS32_sp != kcb->jprobe_saved_sp) { -+ struct pt_regs *saved_regs = &kcb->jprobe_saved_regs; -+ printk(KERN_ERR -+ "current sp %p does not match saved sp %p\n", -+ regs->NDS32_sp, kcb->jprobe_saved_sp); -+ printk(KERN_ERR "Saved registers for jprobe %p\n", jp); -+ show_regs(saved_regs); -+ printk(KERN_ERR "Current registers\n"); -+ show_regs(regs); -+ BUG(); -+ } -+ *regs = kcb->jprobe_saved_regs; -+ memcpy((kprobe_opcode_t *) (kcb->jprobe_saved_sp), -+ kcb->jprobes_stack, -+ MIN_STACK_SIZE(kcb->jprobe_saved_sp)); -+ preempt_enable_no_resched(); -+ return 1; -+ } -+ return 0; -+} -+ -+int __init arch_init_kprobes(void) -+{ -+ return 0; -+} -+ -+int __kprobes arch_trampoline_kprobe(struct kprobe *p) -+{ -+ return 0; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/machine_kexec.c linux-3.4.113/arch/nds32/kernel/machine_kexec.c ---- linux-3.4.113.orig/arch/nds32/kernel/machine_kexec.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/machine_kexec.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,80 @@ -+/* -+ * machine_kexec.c - handle transition of Linux booting another kernel -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern const unsigned char relocate_new_kernel[]; -+extern const unsigned int relocate_new_kernel_size; -+ -+extern void setup_mm_for_reboot(char mode); -+ -+extern unsigned long kexec_start_address; -+extern unsigned long kexec_indirection_page; -+extern unsigned long kexec_mach_type; -+extern unsigned long kexec_boot_atags; -+ -+/* -+ * Provide a dummy crash_notes definition while crash dump arrives to nds32. -+ * This prevents breakage of crash_notes attribute in kernel/ksysfs.c. -+ */ -+ -+int machine_kexec_prepare(struct kimage *image) -+{ -+ return 0; -+} -+ -+void machine_kexec_cleanup(struct kimage *image) -+{ -+} -+ -+void machine_shutdown(void) -+{ -+} -+ -+void machine_crash_shutdown(struct pt_regs *regs) -+{ -+} -+ -+void machine_kexec(struct kimage *image) -+{ -+ unsigned long page_list; -+ unsigned long reboot_code_buffer_phys; -+ void *reboot_code_buffer; -+ -+ page_list = image->head & PAGE_MASK; -+ -+ /* we need both effective and real address here */ -+ reboot_code_buffer_phys = -+ page_to_pfn(image->control_code_page) << PAGE_SHIFT; -+ reboot_code_buffer = page_address(image->control_code_page); -+ -+ /* Prepare parameters for reboot_code_buffer */ -+ kexec_start_address = image->start; -+ kexec_indirection_page = page_list; -+ kexec_mach_type = machine_arch_type; -+ kexec_boot_atags = -+ image->start - KEXEC_NDS32_ZIMAGE_OFFSET + KEXEC_NDS32_ATAGS_OFFSET; -+ -+ /* copy our kernel relocation code to the control code page */ -+ memcpy(reboot_code_buffer, -+ relocate_new_kernel, relocate_new_kernel_size); -+ -+ flush_icache_range((unsigned long)reboot_code_buffer, -+ (unsigned long)reboot_code_buffer + -+ KEXEC_CONTROL_PAGE_SIZE); -+ printk(KERN_INFO "Bye!\n"); -+ -+ cpu_proc_fin(); -+ setup_mm_for_reboot(0); /* mode is not used, so just pass 0 */ -+ cpu_reset(reboot_code_buffer_phys); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/Makefile linux-3.4.113/arch/nds32/kernel/Makefile ---- linux-3.4.113.orig/arch/nds32/kernel/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/Makefile 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,45 @@ -+# -+# Makefile for the linux kernel. -+# -+ -+CPPFLAGS_vmlinux.lds +=-DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) -+AFLAGS_head.o := -DTEXTADDR=$(TEXTADDR) -DDATAADDR=$(DATAADDR) -+ -+# Object file lists. -+ -+obj-y := ex-entry.o ex-exit.o ex-scall.o irq.o \ -+ process.o ptrace.o setup.o signal.o \ -+ sys_nds32.o time.o traps.o io.o proc.o \ -+ elfchk.o -+ifdef CONFIG_FUNCTION_TRACER -+CFLAGS_REMOVE_ftrace.o = -pg -+CFLAGS_REMOVE_ex-entry.o = -pg -+CFLAGS_REMOVE_ex-exit.o = -pg -+CFLAGS_REMOVE_ex-scall.o = -pg -+CFLAGS_REMOVE_stacktrace.o = -pg -+CFLAGS_REMOVE_traps.o = -pg -+endif -+ -+obj-$(CONFIG_MODULES) += nds32_ksyms.o module.o -+obj-$(CONFIG_ISA_DMA) += dma-isa.o -+obj-$(CONFIG_PCI) += bios32.o -+obj-$(CONFIG_SMP) += smp.o -+obj-$(CONFIG_KGDB) += kgdb.o -+obj-$(CONFIG_STACKTRACE) += stacktrace.o -+obj-$(CONFIG_KPROBES) += kprobes.o -+obj-$(CONFIG_FPU) += fpu.o -+obj-$(CONFIG_AUDIO) += audio.o -+obj-$(CONFIG_FUNCTION_GRAPH_TRACER) += ftrace.o -+obj-$(CONFIG_KEXEC) += machine_kexec.o relocate_kernel.o -+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o -+ -+extra-y := head.o init_task.o vmlinux.lds -+ -+CFLAGS_fpu.o += \ -+ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | sed -e 's/NDS32_EXT_FPU_SP/-mext-fpu-sp/') \ -+ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | sed -e 's/NDS32_EXT_FPU_DP/-mext-fpu-dp/') -+ifdef CONFIG_FPU -+CFLAGS_elfchk.o += \ -+ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | sed -e 's/NDS32_EXT_FPU_SP/-mext-fpu-sp/') \ -+ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | sed -e 's/NDS32_EXT_FPU_DP/-mext-fpu-dp/') -+endif -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/module.c linux-3.4.113/arch/nds32/kernel/module.c ---- linux-3.4.113.orig/arch/nds32/kernel/module.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/module.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,314 @@ -+/* -+ * linux/arch/nds32/kernel/module.c -+ * -+ * Copyright (C) 2002 Russell King. -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Module allocation method suggested by Andi Kleen. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+ -+#define DEBUG 0 -+#if DEBUG -+#define PRINTK printk -+#else -+#define PRINTK(x...) -+#endif -+ -+void *module_alloc(unsigned long size) -+{ -+#ifdef CONFIG_KPROBES -+ if (size == 0) -+ return NULL; -+ return vmalloc_exec(size); -+#else -+ return __vmalloc_node_range(size, 1, MODULES_VADDR, MODULES_END, -+ GFP_KERNEL, PAGE_KERNEL, -1, -+ __builtin_return_address(0)); -+#endif -+} -+ -+void module_free(struct module *module, void *region) -+{ -+ vfree(region); -+} -+ -+int module_frob_arch_sections(Elf_Ehdr * hdr, -+ Elf_Shdr * sechdrs, -+ char *secstrings, struct module *mod) -+{ -+ return 0; -+} -+ -+void do_reloc16(unsigned int val, unsigned int *loc, unsigned int val_mask, -+ unsigned int val_shift, unsigned int loc_mask, -+ unsigned int partial_in_place, unsigned int swap) -+{ -+ unsigned int tmp = 0, tmp2 = 0; -+ -+ __asm__ __volatile__("\tlhi.bi\t%0, [%2], 0\n" -+ "\tbeqz\t%3, 1f\n" -+ "\twsbh\t%0, %1\n" -+ "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap) -+ ); -+ -+ tmp2 = tmp & loc_mask; -+ if (partial_in_place) { -+ tmp &= (!loc_mask); -+ tmp = -+ tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask); -+ } else { -+ tmp = tmp2 | ((val & val_mask) >> val_shift); -+ } -+ -+ __asm__ __volatile__("\tbeqz\t%3, 2f\n" -+ "\twsbh\t%0, %1\n" -+ "2:\n" -+ "\tshi.bi\t%0, [%2], 0\n":"=r"(tmp):"0"(tmp), -+ "r"(loc), "r"(swap) -+ ); -+} -+ -+void do_reloc32(unsigned int val, unsigned int *loc, unsigned int val_mask, -+ unsigned int val_shift, unsigned int loc_mask, -+ unsigned int partial_in_place, unsigned int swap) -+{ -+ unsigned int tmp = 0, tmp2 = 0; -+ -+ __asm__ __volatile__("\tlmw.bi\t%0, [%2], %0, 0\n" -+ "\tbeqz\t%3, 1f\n" -+ "\twsbh\t%0, %1\n" -+ "\trotri\t%0, %1, 16\n" -+ "1:\n":"=r"(tmp):"0"(tmp), "r"(loc), "r"(swap) -+ ); -+ -+ tmp2 = tmp & loc_mask; -+ if (partial_in_place) { -+ tmp &= (!loc_mask); -+ tmp = -+ tmp2 | ((tmp + ((val & val_mask) >> val_shift)) & val_mask); -+ } else { -+ tmp = tmp2 | ((val & val_mask) >> val_shift); -+ } -+ -+ __asm__ __volatile__("\tbeqz\t%3, 2f\n" -+ "\twsbh\t%0, %1\n" -+ "\trotri\t%0, %1, 16\n" -+ "2:\n" -+ "\tsmw.bi\t%0, [%2], %0, 0\n":"=r"(tmp):"0"(tmp), -+ "r"(loc), "r"(swap) -+ ); -+} -+ -+static inline int exceed_limit(int offset, unsigned int val_mask, -+ struct module *module, Elf32_Rela * rel, -+ unsigned int relindex, unsigned int reloc_order) -+{ -+ int abs_off = offset < 0 ? ~offset : offset; -+ -+ if (abs_off & (~val_mask)) { -+ printk(KERN_ERR "\n%s: relocation type %d out of range.\n" -+ "please rebuild the kernel module with gcc option \"-Wa,-mno-small-text\".\n", -+ module->name, ELF32_R_TYPE(rel->r_info)); -+ PRINTK("section %d reloc %d offset 0x%x relative 0x%x.\n" -+ relindex, reloc_order, rel->r_offset, offset); -+ return true; -+ } -+ return false; -+} -+ -+#ifdef __NDS32_EL__ -+#define NEED_SWAP 1 -+#else -+#define NEED_SWAP 0 -+#endif -+ -+int -+apply_relocate_add(Elf32_Shdr * sechdrs, const char *strtab, -+ unsigned int symindex, unsigned int relindex, -+ struct module *module) -+{ -+ Elf32_Shdr *symsec = sechdrs + symindex; -+ Elf32_Shdr *relsec = sechdrs + relindex; -+ Elf32_Shdr *dstsec = sechdrs + relsec->sh_info; -+ Elf32_Rela *rel = (void *)relsec->sh_addr; -+ unsigned int i; -+ -+ for (i = 0; i < relsec->sh_size / sizeof(Elf32_Rela); i++, rel++) { -+ Elf32_Addr *loc; -+ Elf32_Sym *sym; -+ Elf32_Addr v; -+ s32 offset; -+ -+ offset = ELF32_R_SYM(rel->r_info); -+ if (offset < 0 -+ || offset > (symsec->sh_size / sizeof(Elf32_Sym))) { -+ printk(KERN_ERR "%s: bad relocation\n", module->name); -+ PRINTK("section %d reloc %d\n", module->name, relindex, -+ i); -+ return -ENOEXEC; -+ } -+ -+ sym = ((Elf32_Sym *) symsec->sh_addr) + offset; -+ -+ if (rel->r_offset < 0 -+ || rel->r_offset > dstsec->sh_size - sizeof(u16)) { -+ printk(KERN_ERR "%s: out of bounds relocation\n", -+ module->name); -+ PRINTK("section %d reloc %d offset 0x%0x size %d\n", -+ relindex, i, rel->r_offset, dstsec->sh_size); -+ return -ENOEXEC; -+ } -+ -+ loc = (Elf32_Addr *) (dstsec->sh_addr + rel->r_offset); -+ v = sym->st_value + rel->r_addend; -+ -+ switch (ELF32_R_TYPE(rel->r_info)) { -+ case R_NDS32_NONE: -+ case R_NDS32_INSN16: -+ case R_NDS32_LABEL: -+ case R_NDS32_LONGCALL1: -+ case R_NDS32_LONGCALL2: -+ case R_NDS32_LONGCALL3: -+ case R_NDS32_LONGCALL4: -+ case R_NDS32_LONGJUMP1: -+ case R_NDS32_LONGJUMP2: -+ case R_NDS32_LONGJUMP3: -+ case R_NDS32_9_FIXED_RELA: -+ case R_NDS32_15_FIXED_RELA: -+ case R_NDS32_17_FIXED_RELA: -+ case R_NDS32_25_FIXED_RELA: -+ case R_NDS32_LOADSTORE: -+ case R_NDS32_DWARF2_OP1_RELA: -+ case R_NDS32_DWARF2_OP2_RELA: -+ case R_NDS32_DWARF2_LEB_RELA: -+ case R_NDS32_RELA_NOP_MIX...R_NDS32_RELA_NOP_MAX: -+ break; -+ -+ case R_NDS32_32_RELA: -+ do_reloc32(v, loc, 0xffffffff, 0, 0, 0, 0); -+ break; -+ -+ case R_NDS32_HI20_RELA: -+ do_reloc32(v, loc, 0xfffff000, 12, 0xfff00000, 0, -+ NEED_SWAP); -+ break; -+ -+ case R_NDS32_LO12S3_RELA: -+ do_reloc32(v, loc, 0x00000fff, 3, 0xfffff000, 0, -+ NEED_SWAP); -+ break; -+ -+ case R_NDS32_LO12S2_RELA: -+ do_reloc32(v, loc, 0x00000fff, 2, 0xfffff000, 0, -+ NEED_SWAP); -+ break; -+ -+ case R_NDS32_LO12S1_RELA: -+ do_reloc32(v, loc, 0x00000fff, 1, 0xfffff000, 0, -+ NEED_SWAP); -+ break; -+ -+ case R_NDS32_LO12S0_RELA: -+ case R_NDS32_LO12S0_ORI_RELA: -+ do_reloc32(v, loc, 0x00000fff, 0, 0xfffff000, 0, -+ NEED_SWAP); -+ break; -+ -+ case R_NDS32_9_PCREL_RELA: -+ if (exceed_limit -+ ((v - (Elf32_Addr) loc), 0x000000ff, module, rel, -+ relindex, i)) -+ return -ENOEXEC; -+ do_reloc16(v - (Elf32_Addr) loc, loc, 0x000001ff, 1, -+ 0xffffff00, 0, NEED_SWAP); -+ break; -+ -+ case R_NDS32_15_PCREL_RELA: -+ if (exceed_limit -+ ((v - (Elf32_Addr) loc), 0x00003fff, module, rel, -+ relindex, i)) -+ return -ENOEXEC; -+ do_reloc32(v - (Elf32_Addr) loc, loc, 0x00007fff, 1, -+ 0xffffc000, 0, NEED_SWAP); -+ break; -+ -+ case R_NDS32_17_PCREL_RELA: -+ if (exceed_limit -+ ((v - (Elf32_Addr) loc), 0x0000ffff, module, rel, -+ relindex, i)) -+ return -ENOEXEC; -+ do_reloc32(v - (Elf32_Addr) loc, loc, 0x0001ffff, 1, -+ 0xffff0000, 0, NEED_SWAP); -+ break; -+ -+ case R_NDS32_25_PCREL_RELA: -+ if (exceed_limit -+ ((v - (Elf32_Addr) loc), 0x00ffffff, module, rel, -+ relindex, i)) -+ return -ENOEXEC; -+ do_reloc32(v - (Elf32_Addr) loc, loc, 0x01ffffff, 1, -+ 0xff000000, 0, NEED_SWAP); -+ break; -+ case R_NDS32_WORD_9_PCREL_RELA: -+ if (exceed_limit -+ ((v - (Elf32_Addr) loc), 0x000000ff, module, rel, -+ relindex, i)) -+ return -ENOEXEC; -+ do_reloc32(v - (Elf32_Addr) loc, loc, 0x000001ff, 1, -+ 0xffffff00, 0, NEED_SWAP); -+ break; -+ -+ case R_NDS32_SDA15S3_RELA: -+ case R_NDS32_SDA15S2_RELA: -+ case R_NDS32_SDA15S1_RELA: -+ case R_NDS32_SDA15S0_RELA: -+ printk(KERN_ERR "%s: unsupported relocation type %d.\n", -+ module->name, ELF32_R_TYPE(rel->r_info)); -+ printk(KERN_ERR -+ "Small data section access doesn't work in the kernel space; " -+ "please rebuild the kernel module with gcc option -G0.\n"); -+ PRINTK("section %d reloc %d offset 0x%x size %d\n", -+ relindex, i, rel->r_offset, dstsec->sh_size); -+ break; -+ -+ default: -+ printk(KERN_ERR "%s: unsupported relocation type %d.\n", -+ module->name, ELF32_R_TYPE(rel->r_info)); -+ PRINTK("section %d reloc %d offset 0x%x size %d\n", -+ relindex, i, rel->r_offset, dstsec->sh_size); -+ } -+ } -+ return 0; -+} -+ -+int -+apply_relocate(Elf32_Shdr * sechdrs, const char *strtab, -+ unsigned int symindex, unsigned int relsec, -+ struct module *module) -+{ -+// printk(KERN_ERR "module %s: non-ADD RELOCATION unsupported\n", module->name); -+// return -ENOEXEC; -+ return 0; -+} -+ -+int -+module_finalize(const Elf32_Ehdr * hdr, const Elf_Shdr * sechdrs, -+ struct module *module) -+{ -+ return 0; -+} -+ -+void module_arch_cleanup(struct module *mod) -+{ -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/nds32-elf.h linux-3.4.113/arch/nds32/kernel/nds32-elf.h ---- linux-3.4.113.orig/arch/nds32/kernel/nds32-elf.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/nds32-elf.h 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,855 @@ -+#ifndef _NDS32_ELF_CHECK -+#define _NDS32_ELF_CHECK -+ -+//#define TEST_ELF_CHECK_FUNC -+#ifdef TEST_ELF_CHECK_FUNC -+#include -+#include -+#endif -+ -+//#include -+//#include -+ -+#ifdef __cplusplus -+extern "C" -+{ -+#else -+#include -+#endif //#ifdef __cplusplus -+ -+ -+ enum ELF_HEADER_FLAG_FIELD -+ { -+ EHFF_ARCH_VER = 0xF0000000, EHFF_ARCH_VER_SHIFT = 28, -+ //EHFF_RESERVED = 0x08000000, -+ EHFF_HAS_ZOL = 0x04000000, -+ EHFF_ISA_DSP = 0x02000000, -+ EHFF_ISA_FPU_MAC = 0x01000000, -+ EHFF_FPU_REG = 0x00C00000, EHFF_FPU_REG_SHIFT = 22, -+ EHFF_ISA_L2C = 0x00200000, -+ EHFF_ISA_NO_MAC = 0x00100000, -+ EHFF_ISA_MAC_DX = 0x00100000, -+ EHFF_ISA_FPU_DP = 0x00080000, -+ //EHFF_RESERVED = 0x00040000, -+ EHFF_ISA_SATURATION = 0x00020000, -+ EHFF_REDUCED_REGS = 0x00010000, -+ EHFF_ISA_STRING = 0x00008000, -+ EHFF_ISA_16BIT = 0x00004000, -+ EHFF_ISA_IFC = 0x00004000, -+ EHFF_ISA_DIV = 0x00002000, -+ EHFF_ISA_DIV_DX = 0x00002000, -+ EHFF_ISA_AUDIO = 0x00001000, -+ EHFF_ISA_FPU_SP = 0x00000800, -+ EHFF_ISA_EXT2 = 0x00000400, -+ EHFF_ISA_EXT = 0x00000200, -+ EHFF_ISA_EIT = 0x00000100, -+ EHFF_ISA_MFUSR_PC = 0x00000100, -+ EHFF_ABI_VER = 0x000000F0, -+ EHFF_ELF_VER = 0x0000000F, EHFF_ELF_VER_SHIFT = 0, -+ }; -+ -+ -+ enum ELF_HEADER_FLAG_FIELD_ARCH_VER -+ { -+ EHFF_ARCH_VER_RESERVED = 0x0, -+ EHFF_ARCH_VER_V1 = 0x1, -+ EHFF_ARCH_VER_V2 = 0x2, -+ EHFF_ARCH_VER_V3 = 0x3, -+ EHFF_ARCH_VER_V3M = 0x4, -+ }; -+ -+ static const char *EHFF_ARCH_VER_MSG[] = -+ { -+ "RESERVED", -+ "BASE V1", -+ "BASE V2", -+ "BASE V3", -+ "BASE V3M", -+ }; -+ -+ -+ -+ -+ /* ----------------------------------------------------------- */ -+ /* 4-bit for ABI signature, allow up to 16 ABIs */ -+ /* 0 : for OLD ABI V0, phase out -+ * 1 : for V1 , starting with V0 toolchain -+ * 2 : for V2 -+ * 3 : for V2FP (fs0, fs1 as function parameter) -+ * 4 : for AABI */ -+ /* only old N1213HC use V0 */ -+ /* New ABI is used due to return register is changed to r0 from r5 */ -+ /* ----------------------------------------------------------- */ -+#define E_NDS_ABI_V0 0x00000000 -+#define E_NDS_ABI_V1 0x00000010 -+#define E_NDS_ABI_V2 0x00000020 -+#define E_NDS_ABI_V2FP 0x00000030 -+#define E_NDS_ABI_AABI 0x00000040 -+#define E_NDS_ABI_V2FP_PLUS 0x00000050 -+ -+ /* ---------------------------------------------------------------------------- */ -+ /* This flag signifies the version of Andes ELF */ -+ /* note : */ -+ /* 1. v1.3.1 and beyond is accompanying with Baseline ISA 1.0b/2.0/... in ELF. */ -+ /* 2. v1.3.1 is accompanying with Baseline ISA 1.0b in ELF. */ -+ /* ... | MAC | ... | DIV | ... */ -+ /* 3. v1.3.1 is accompanying with Baseline ISA 2.0 and beyond in ELF. */ -+ /* ... | MAC_DX | ... | DIV_DX | ... */ -+ /* ---------------------------------------------------------------------------- */ -+ -+ enum ELF_HEADER_FLAG_FIELD_ELF_VER -+ { -+ EHFF_ELF_VER_1_3_0 = 0x0, -+ EHFF_ELF_VER_1_3_1 = 0x1, -+ EHFF_ELF_VER_1_4_0 = 0x2, -+ }; -+ -+ static const char *EHFF_ELF_VER_MSG[] = -+ { -+ "1.3.0", -+ "1.3.1", -+ "1.4.0", -+ }; -+ /* */ -+ /* sr layout : */ -+ /* sr[14..10] : hardware components */ -+ /* cpu / fpu / audio / ... */ -+ /* sr[9..0] : sr index number dedicated for sr[14..10] */ -+ /* */ -+ -+ // -+ // sr[14..10] definition: -+ // 0 : cpu -+ // 1 : fpu -+ // 2 : audio -+#define INDEX_HW_MASK 0x00007c00 -+#define INDEX_HW_CPU 0x00000000 -+#define INDEX_HW_FPU 0x00000400 -+#define INDEX_HW_AUDIO 0x00000800 -+#define HW_IS_CPU(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_CPU) -+#define HW_IS_FPU(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_FPU) -+#define HW_IS_AUDIO(sr) ((sr & INDEX_HW_MASK) == INDEX_HW_AUDIO) -+ -+ // -+ // sr[9..0] definition: -+ // if (HW_IS_CPU(sr)) // cpu score -+ // sr[9..0] defined in chap 9 of Andes-Privilege-Architecture spec. -+ // else if (HW_IS_FPU(sr)) // fpu score -+ // sr[9..0] == SR_FPU_FPCFG, FPCFG defined in FPU_ISA_EXT spec. -+ // else if (HW_IS_AUDIO(sr)) // audio score -+ // //none register is used in loader checking mechanism -+ // -+#define SR_INDEX_MASK 0x000003ff -+#define SR_INDEX(sr) (sr & SR_INDEX_MASK) -+#define CPU_SR_INDEX(x,y,z) ((x << 7) + (y << 3) + z) -+#define FPU_SR_FPCFG() (INDEX_HW_FPU) -+ -+ //FPU-belonged system registers -+#define SR_FPU_FPCFG 0x00 -+ -+#define SR_NOT_EXIST 0xffffffff -+ -+ typedef unsigned int (* CALLBACK_FUNC) (unsigned int index); -+ -+ -+ static const char *NEC_MSG_FPU_reg[5] = -+ { -+ "N/A", -+ " 8SP/ 4DP", -+ "16SP/ 8DP", -+ "32SP/16DP", -+ "32SP/32DP" -+ }; -+ static const char *NEC_MSG_endian[2] = -+ { -+ "little", -+ "big" -+ }; -+ -+#define EM_NDS32 167 -+#if defined elf_check_swap_2 || defined elf_check_swap_4 -+#error "ERROR : elf_check_swap_2 and elf_check_swap_4 are multiple defined" -+#endif -+#define elf_check_swap_2(data) (((data&0x0000ff00)>>8) | ((data&0x000000ff)<<8)) -+#define elf_check_swap_4(data) (((data&0xff000000)>>24) | \ -+ ((data&0x00ff0000)>>8) | \ -+ ((data&0x0000ff00)<<8) | \ -+ ((data&0x000000ff)<<24)) -+ -+#define MSC_CFG_BASEV 0x0000e000 -+ -+#define CPU_VER_EXT 0x00000001 -+#define CPU_VER_A16 0x00000002 -+#define CPU_VER_EXT2 0x00000004 -+#define CPU_VER_FPU 0x00000008 -+#define CPU_VER_STRING 0x00000010 -+#define CPU_VER_SATURATION 0x00000020 -+ -+#define MSC_CFG_DIV 0x00000020 -+#define MSC_CFG_MAC 0x00000040 -+#define MSC_CFG_L2C 0x00000200 -+#define MSC_CFG_REDUCED_REG 0x00000400 -+#define MSC_CFG_NOD 0x00010000 -+#define MSC_CFG_AUDIO 0x00000180 -+#define MSC_CFG_AUDIO_NONE 0x00000000 -+#define MSC_CFG_IFC 0x00080000 -+#define MSC_CFG_MCU 0x00100000 -+#define MSC_CFG_EX9IT 0x01000000 -+#define MSC_CFG_MSC_EXT 0xc0000000 -+ -+#define MSC_CFG2_DSPPF 0x00000018 -+#define MSC_CFG2_ZOL 0x00000020 -+ -+#define MMU_CFG_DE 0x04000000 -+ -+ typedef struct nds32_elfinfo_s -+ { -+ unsigned int endian; // 1.local-used constant definition -+ // 0 : little , 1 : big -+ // 2.system-used constant definition -+ // little / big depends on system definition -+ unsigned int machine; //magic number (167 for nds32 machine) -+ unsigned int mfusr_pc; //reclaim in baseline v2 -+ unsigned int abi; // abi version -+ unsigned int base16; // 0 : not support , 1 : support -+ unsigned int pex1; -+ unsigned int div; //reclaim in baseline v2 -+ unsigned int pex2; -+ unsigned int fpu; //fpu single precision -+ unsigned int audio; -+ unsigned int string; -+ unsigned int reduced_regs; -+ unsigned int saturation; -+ unsigned int ifc; -+ unsigned int elf_ver; //elf version number, 0 for v1.3.0, 1 for v1.3.1 -+ unsigned int l2c; -+ unsigned int mac; //reclaim in baseline v2 -+ //unsigned int isa_ver;//0x0, baseline = baseline V1 - 16 bit ISA -+ //0x1, baseline = baseline V1 -+ //0x2, baseline = baseline V1 + V2 extension ISA -+ //unsigned int fpu_sp; //fpu double precision -+ //unsigned int fpu_reg; //fpu registers capacity -+ } nds32_elfinfo_t; -+ -+ typedef enum nds32_elfchk_e -+ { -+ endian_chk = 0, -+ machine_chk, -+ isa_chk, -+ abi_chk -+ } nds32_elfchk_t; -+ -+ typedef enum ELF_Fail_Type -+ { -+ EFT_NONE, -+ EFT_WARNING, -+ EFT_ERROR -+ }ELF_Fail_Type; -+ -+ static inline void NEC_itoa(unsigned int value, char *buf, const unsigned int base) -+ { -+ char temp[10] = "\0", ch; -+ int len = 1, index; -+ -+ while(value > 0) -+ { -+ ch = value%base; -+ value = value/base; -+ if(ch >= 10) -+ ch = ch+'a'-10; -+ else -+ ch = ch+'0'; -+ temp[len++] = ch; -+ } -+ len--; -+ -+ index = len; -+ while(index >= 0) -+ { -+ buf[index] = temp[len-index]; -+ index--; -+ } -+ } -+ -+ static inline void NEC_format(char *buf, unsigned int width) -+ { -+ unsigned int len = strlen(buf); -+ memmove(buf+(width-len), buf, len+1); -+ memset(buf, ' ', (width-len)); -+ } -+ -+ static void NEC_sprintf(char *buf, const char *str, ...) -+ { -+ int width, len = 0; -+ va_list ap; -+ char token, temp[100]; -+ buf[0] = '\0'; -+ -+ -+ va_start(ap, str); -+ while(*str != '\0') -+ { -+ if(*str != '%') -+ buf[len++] = *str; -+ else //*str == '%' -+ { -+ token = *(++str); -+ -+ width = 0; -+ while(token >= '0' && token <= '9') -+ { -+ width *= 10; -+ width += token-'0'; -+ token = *(++str); -+ } -+ -+ switch(token) -+ { -+ case 'd': -+ NEC_itoa(va_arg(ap, unsigned int), temp, 10); -+ break; -+ case 'x': -+ NEC_itoa(va_arg(ap, unsigned int), temp, 16); -+ break; -+ case 's': -+ strcpy(temp, va_arg(ap, char *)); -+ break; -+ } -+ -+ if(width != 0) -+ NEC_format(temp, width); -+ -+ buf[len++] = '\0'; -+ strcat(buf, temp); -+ len = strlen(buf); -+ } -+ -+ str++; -+ } -+ buf[len] = '\0'; -+ } -+ -+ //NDS32 strcat for avoiding buf overflow -+ static inline void NEC_strcat_safety(char *destination, unsigned int destination_size, char *source) -+ { -+ strncat(destination, source, destination_size - strlen(destination) - 1); -+ } -+ -+ //NDS32 Elf Check print -+ static inline void NEC_print(char *buf, unsigned int len, ELF_Fail_Type type, const char *name, const char *cpu, const char *elf, const char *error_message) -+ { -+ char temp[100]; -+ switch(type) -+ { -+ case EFT_NONE: -+ NEC_sprintf(temp, "\t | %9s | %9s | %14s\n", cpu, elf, name); -+ break; -+ case EFT_WARNING: -+ NEC_sprintf(temp, "\t?| %9s | %9s | %14s Warning: %s\n", cpu, elf, name, error_message); -+ break; -+ case EFT_ERROR: -+ NEC_sprintf(temp, "\t!| %9s | %9s | %14s Error: %s\n", cpu, elf, name, error_message); -+ break; -+ } -+ NEC_strcat_safety(buf, len, temp); -+ } -+ -+ static inline bool NEC_check_bool(char *buf, unsigned int len, ELF_Fail_Type type, const char *isa, bool cpu, bool elf) -+ { -+ bool code; -+ const char *NEC_MSG_ISA[2] = { "OFF", "ON" }; -+ if(!cpu && elf) -+ code = 1; -+ else -+ { -+ code = 0; -+ type = EFT_NONE; -+ } -+ NEC_print(buf, len, type, isa, NEC_MSG_ISA[cpu], NEC_MSG_ISA[elf], "Not supported by CPU"); -+ return code; -+ } -+ -+ static inline ELF_Fail_Type elf_ver_and_arch_ver_compatibility_check(unsigned int elf_ver, unsigned int arch_ver) -+ { -+ switch(elf_ver) -+ { -+ case EHFF_ELF_VER_1_3_0: -+ switch(arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ case EHFF_ELF_VER_1_3_1: -+ switch(arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ case EHFF_ARCH_VER_V2: -+ case EHFF_ARCH_VER_V3M: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ case EHFF_ELF_VER_1_4_0: -+ switch(arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ case EHFF_ARCH_VER_V2: -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ } -+ return EFT_ERROR; -+ } -+ -+ -+ static inline ELF_Fail_Type arch_ver_check(unsigned int CPU, unsigned int ELF) -+ { -+ switch(CPU) -+ { -+ case EHFF_ARCH_VER_V1: -+ switch(ELF) -+ { -+ case EHFF_ARCH_VER_V1: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ case EHFF_ARCH_VER_V2: -+ switch(ELF) -+ { -+ case EHFF_ARCH_VER_V1: -+ case EHFF_ARCH_VER_V2: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ case EHFF_ARCH_VER_V3: -+ switch(ELF) -+ { -+ case EHFF_ARCH_VER_V1: -+ case EHFF_ARCH_VER_V2: -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ case EHFF_ARCH_VER_V3M: -+ switch(ELF) -+ { -+ case EHFF_ARCH_VER_V3M: -+ return EFT_NONE; -+ default: -+ return EFT_ERROR; -+ } -+ } -+ return EFT_ERROR; -+ } -+ -+ // buf : buffer of char*, put Target Isa Info into *buf -+ // len : length of buffer (at least 300 chars in length) -+ // buf_status : status of buffer -+ // 0 : ok -+ // 1 : overflow -+#define TARGET_ISA_INFO_LEN 2000 -+ static inline unsigned int elf_check (unsigned char *ehdr, CALLBACK_FUNC reg_read_callback, char *buf, unsigned int len, unsigned int *buf_status) -+ { -+ unsigned int SR_msc_cfg, SR_msc_cfg2 = 0, SR_cpu_ver, SR_mmu_cfg, fpcfg, fucop_exist, fpu_mount; -+ unsigned int CPU_DIV_DX_ISA, CPU_MAC_DX_ISA; -+ unsigned int eflag, ELF_arch_ver, ELF_elf_ver, CPU_arch_ver; -+ unsigned short machine; -+ unsigned char big_endian_elf = 0, big_endian_cpu; -+ -+ char temp[100]; -+ char temp_cpu[10]; -+ char temp_elf[10]; -+ int n_error, n_warning; -+ int CPU_support; -+ unsigned char FPU_reg_elf, FPU_reg_cpu; -+ ELF_Fail_Type error_type; -+ -+ -+ -+ n_error = 0; -+ n_warning = 0; -+ -+ buf[0] = '\0'; -+ *buf_status = 0; -+ -+ SR_cpu_ver = reg_read_callback(CPU_SR_INDEX(0,0,0)); -+ SR_msc_cfg = reg_read_callback(CPU_SR_INDEX(0,4,0)); -+ SR_mmu_cfg = reg_read_callback(CPU_SR_INDEX(0,3,0)); -+ -+ if (SR_msc_cfg & MSC_CFG_MSC_EXT) -+ SR_msc_cfg2 = reg_read_callback(CPU_SR_INDEX(0,4,1)); -+ -+ switch(*((char*)(ehdr+5))) -+ { -+ case 1: -+ big_endian_elf = 0; -+ break; -+ case 2: -+ big_endian_elf = 1; -+ break; -+ } -+ -+ if(SR_mmu_cfg & MMU_CFG_DE) -+ big_endian_cpu = 1; -+ else -+ big_endian_cpu = 0; -+ -+ -+ /* 20091106 note : -+ * 1. In term of OS, elf_check() would be used in OS kernel and ld.so -+ * 2. Since OS is running on SID, eflag/machine did not need endian conversion for big endian format. -+ * 3. Later, elf_check interface is going to cover "OS" case by adding a new parameter. -+ * -+ */ -+#ifdef ELF_CHECKING_OS -+ eflag = *((unsigned int *)(ehdr+36)); -+ machine = *((unsigned short*)(ehdr+18)); -+#else // GDB loader / SID loader -+ eflag = (big_endian_elf == 0)? *((unsigned int *)(ehdr+36)) : elf_check_swap_4(*((unsigned int *)(ehdr+36))); -+ machine = (big_endian_elf == 0)? *((unsigned short*)(ehdr+18)) : elf_check_swap_2(*((unsigned short*)(ehdr+18))); -+#endif -+ -+ ELF_arch_ver = (eflag & EHFF_ARCH_VER) >> EHFF_ARCH_VER_SHIFT; -+ ELF_elf_ver = (eflag & EHFF_ELF_VER) >> EHFF_ELF_VER_SHIFT; -+ -+ CPU_arch_ver = ((SR_msc_cfg & MSC_CFG_BASEV) >> 13) + 1; -+ if(CPU_arch_ver == 3) -+ if(SR_msc_cfg & MSC_CFG_MCU) -+ CPU_arch_ver = 4; -+ -+ /*Basic version check -+ -+ 1.ELF version check -+ 2.Architecture version check -+ 3.Machine check -+ */ -+ if(ELF_elf_ver > EHFF_ELF_VER_1_4_0) -+ { -+ NEC_sprintf(temp, "Error: unsupport ELF version: 0x%x\n", ELF_elf_ver); -+ NEC_strcat_safety(buf, len, temp); -+ return 1; -+ } -+ NEC_sprintf(temp, "ELF version: %s\n", EHFF_ELF_VER_MSG[ELF_elf_ver]); -+ NEC_strcat_safety(buf, len, temp); -+ -+ -+ if(elf_ver_and_arch_ver_compatibility_check(ELF_elf_ver, ELF_arch_ver) == EFT_ERROR) -+ { -+ NEC_sprintf(temp, "Error: architecture version is not supported in this ELF version: %s\n", EHFF_ARCH_VER_MSG[ELF_arch_ver]); -+ NEC_strcat_safety(buf, len, temp); -+ return 1; -+ } -+ -+ NEC_sprintf(temp, "\t %9s %9s \n", "CPU", "ELF"); -+ NEC_strcat_safety(buf, len, temp); -+ if(big_endian_cpu != big_endian_elf) -+ { -+ error_type = EFT_ERROR; -+ n_error++; -+ } -+ else -+ error_type = EFT_NONE; -+ NEC_print(buf, len, error_type, "endianess", NEC_MSG_endian[big_endian_cpu], NEC_MSG_endian[big_endian_elf], "endianess mismatch"); -+ -+ -+ -+ -+ if (EM_NDS32 != machine) -+ { -+ error_type = EFT_ERROR; -+ n_error++; -+ } -+ else -+ error_type = EFT_NONE; -+ NEC_sprintf(temp_cpu, "%d", EM_NDS32); -+ NEC_sprintf(temp_elf, "%d", machine); -+ NEC_print(buf, len, error_type, "machine", temp_cpu, temp_elf, "wrong machine"); -+ -+ -+ error_type = arch_ver_check(CPU_arch_ver, ELF_arch_ver); -+ if(error_type == EFT_ERROR) -+ n_error++; -+ NEC_print(buf, len, error_type, "BASELINE ISA", EHFF_ARCH_VER_MSG[CPU_arch_ver], EHFF_ARCH_VER_MSG[ELF_arch_ver], "BASELINE ISA mismatch"); -+ -+ /*Prepare reference variables -+ -+ 1.DIV, MAC, DX -+ 2.FPU -+ */ -+ -+ CPU_MAC_DX_ISA = 0; -+ CPU_DIV_DX_ISA = 0; -+ switch(CPU_arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ if (SR_msc_cfg & MSC_CFG_MAC) -+ CPU_MAC_DX_ISA = 1; -+ if (SR_msc_cfg & MSC_CFG_DIV) -+ CPU_DIV_DX_ISA = 1; -+ break; -+ case EHFF_ARCH_VER_V2: -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ if (!(SR_msc_cfg & MSC_CFG_NOD)) -+ { -+ CPU_MAC_DX_ISA = 1; -+ CPU_DIV_DX_ISA = 1; -+ } -+ break; -+ } -+ fpu_mount = 0; -+ if (SR_cpu_ver & CPU_VER_FPU) -+ { -+ fucop_exist = reg_read_callback(CPU_SR_INDEX(0,5,0)); -+ if (fucop_exist & 0x80000000) -+ { -+ fpu_mount = 1; -+ fpcfg = reg_read_callback(FPU_SR_FPCFG()); -+ } -+ else -+ fpu_mount = 0; -+ } -+ -+ //Parse Configuration field (bit 27~8) -+ -+ //bit 27 Reserved -+ //bit 26 ZOL -+ CPU_support = 0; -+ if ((SR_msc_cfg & MSC_CFG_MSC_EXT) && (SR_msc_cfg2 & MSC_CFG2_ZOL)) -+ CPU_support = 1; -+ if (ELF_elf_ver == EHFF_ELF_VER_1_4_0) -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "ZOL", CPU_support, eflag & EHFF_HAS_ZOL); -+ -+ //bit 25 DSP -+ CPU_support = 0; -+ if ((SR_msc_cfg & MSC_CFG_MSC_EXT) && (SR_msc_cfg2 & MSC_CFG2_DSPPF)) -+ CPU_support = 1; -+ if (ELF_elf_ver == EHFF_ELF_VER_1_4_0) -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "DSP ISA", CPU_support, eflag & EHFF_ISA_DSP); -+ -+ //bit 24 -+ CPU_support = 0; -+ if(fpu_mount) -+ if(fpcfg & 0x00000010) -+ CPU_support = 1; -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU MAC ISA", CPU_support, eflag & EHFF_ISA_FPU_MAC); -+ -+ //bit 23~22 -+ if(fpu_mount) -+ FPU_reg_cpu = ((fpcfg >> 2) & 0x3) + 1; -+ else -+ FPU_reg_cpu = 0; -+ -+ if(eflag & (EHFF_ISA_FPU_SP | EHFF_ISA_FPU_DP | EHFF_ISA_FPU_MAC)) -+ FPU_reg_elf = ((eflag & EHFF_FPU_REG) >> EHFF_FPU_REG_SHIFT) + 1; -+ else -+ FPU_reg_elf = 0; -+ if(FPU_reg_elf > FPU_reg_cpu) -+ { -+ error_type = EFT_ERROR; -+ n_error++; -+ } -+ else -+ error_type = EFT_NONE; -+ NEC_print(buf, len, error_type, "FPU REGISTER", NEC_MSG_FPU_reg[FPU_reg_cpu], NEC_MSG_FPU_reg[FPU_reg_elf], -+ "FPU REGISTERS not supported by CPU"); -+ //bit 21 -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "L2C ISA", SR_msc_cfg & MSC_CFG_L2C, eflag & EHFF_ISA_L2C); -+ -+ //bit 20 -+ //MAC_DX check -+ // Target Machine certainly has MAC_DX under the following conditions: -+ // 1. Baseline V1 ISA && MSC_CFG.MAC (softcore version) -+ // 2. Baseline V2 ISA && D0/D1 support -+ // 3. Baseline V3 ISA && D0/D1 support -+ -+ switch(ELF_arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MAC/MAC DX ISA", CPU_MAC_DX_ISA, !(eflag & EHFF_ISA_NO_MAC)); -+ break; -+ case EHFF_ARCH_VER_V2: -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MAC DX ISA", CPU_MAC_DX_ISA, eflag & EHFF_ISA_MAC_DX); -+ break; -+ } -+ //bit 19 -+ CPU_support = 0; -+ if(fpu_mount) -+ if(fpcfg & 0x00000002) -+ CPU_support = 1; -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU DP ISA", CPU_support, eflag & EHFF_ISA_FPU_DP); -+ -+ -+ //bit 18 Reserved -+ //bit 17 -+ switch(ELF_elf_ver) -+ { -+ case EHFF_ELF_VER_1_3_0: -+ case EHFF_ELF_VER_1_3_1: -+ break; -+ case EHFF_ELF_VER_1_4_0: -+ switch(ELF_arch_ver) -+ { -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "SATURATION ISA", SR_cpu_ver & CPU_VER_SATURATION, eflag & EHFF_ISA_SATURATION); -+ break; -+ } -+ break; -+ } -+ //bit 16 -+ if(SR_msc_cfg & MSC_CFG_REDUCED_REG) -+ CPU_support = 0; -+ else -+ CPU_support = 1; -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "32 GPR", CPU_support, (eflag & EHFF_REDUCED_REGS) == 0); -+ -+ //bit 15 -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "STRING ISA", SR_cpu_ver & CPU_VER_STRING, eflag & EHFF_ISA_STRING); -+ -+ //bit 14 -+ switch(ELF_elf_ver) -+ { -+ case EHFF_ELF_VER_1_3_0: -+ case EHFF_ELF_VER_1_3_1: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "16-BIT ISA", SR_cpu_ver & CPU_VER_A16, eflag & EHFF_ISA_16BIT); -+ break; -+ case EHFF_ELF_VER_1_4_0: -+ switch(ELF_arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ case EHFF_ARCH_VER_V2: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "16-BIT ISA", SR_cpu_ver & CPU_VER_A16, eflag & EHFF_ISA_16BIT); -+ break; -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "IFC ISA", SR_msc_cfg & MSC_CFG_IFC, eflag & EHFF_ISA_IFC); -+ break; -+ } -+ break; -+ } -+ -+ //bit 13 -+ switch(ELF_arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "DIV DX ISA", CPU_DIV_DX_ISA, eflag & EHFF_ISA_DIV); -+ break; -+ case EHFF_ARCH_VER_V2: -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "DIV DX ISA", CPU_DIV_DX_ISA, eflag & EHFF_ISA_DIV_DX); -+ break; -+ } -+ //bit 12 -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "AUDIO/DSP ISA", SR_msc_cfg & MSC_CFG_AUDIO, eflag & EHFF_ISA_AUDIO); -+ //bit 11 -+ CPU_support = 0; -+ if(fpu_mount) -+ if(fpcfg & 0x00000001) -+ CPU_support = 1; -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "FPU SP ISA", CPU_support, eflag & EHFF_ISA_FPU_SP); -+ -+ //bit 10 -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "PEX2 ISA", SR_cpu_ver & CPU_VER_EXT2, eflag & EHFF_ISA_EXT2); -+ -+ //bit 9 -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "PEX1 ISA", SR_cpu_ver & CPU_VER_EXT, eflag & EHFF_ISA_EXT); -+ -+ //bit 8 -+ CPU_support = 0; -+ if(CPU_arch_ver == EHFF_ARCH_VER_V3M) -+ CPU_support = 1; -+ switch(ELF_elf_ver) -+ { -+ case EHFF_ELF_VER_1_3_0: -+ case EHFF_ELF_VER_1_3_1: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MFUSR_PC ISA", CPU_support, eflag & EHFF_ISA_MFUSR_PC); -+ break; -+ case EHFF_ELF_VER_1_4_0: -+ switch(ELF_arch_ver) -+ { -+ case EHFF_ARCH_VER_V1: -+ case EHFF_ARCH_VER_V2: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "MFUSR_PC ISA", CPU_support, eflag & EHFF_ISA_MFUSR_PC); -+ break; -+ case EHFF_ARCH_VER_V3: -+ case EHFF_ARCH_VER_V3M: -+ n_error += NEC_check_bool(buf, len, EFT_ERROR, "EIT ISA", SR_msc_cfg & MSC_CFG_EX9IT, eflag & EHFF_ISA_EIT); -+ break; -+ } -+ break; -+ } -+ -+ if(n_error) -+ { -+ NEC_strcat_safety(buf, len, (char*)"Error: ELF and CPU mismatch\n"); -+ NEC_sprintf(temp, "Total Error: %d\n", n_error); -+ NEC_strcat_safety(buf, len, temp); -+ -+ NEC_strcat_safety(buf, len, (char*)"Usage error, Consult Andes Toolchains and their compatible Andes cores for the Toolchain-CPU compatibility.\n"); -+ NEC_strcat_safety(buf, len, (char*)"The Loader Checking can be disabled under Debug Configuration.\n"); -+ } -+ else -+ NEC_strcat_safety(buf, len, (char*)"NDS32 ELF checking pass\n"); -+ -+ if(n_warning) -+ { -+ NEC_sprintf(temp, "Total Warning: %d\n", n_warning); -+ NEC_strcat_safety(buf, len, temp); -+ } -+ -+ -+ // checking buf overflow -+ if(strlen(buf) >= len) -+ *buf_status = 1; -+ -+ return n_error; -+ } //end of elf_check -+ -+#undef elf_check_swap_2 -+#undef elf_check_swap_4 -+ -+#undef MSC_CFG_BASEV -+ -+#undef CPU_VER_STRING -+#undef CPU_VER_EXT -+#undef CPU_VER_A16 -+#undef CPU_VER_EXT2 -+#undef CPU_VER_FPU -+#undef CPU_VER_SATURATION -+ -+#undef MSC_CFG_DIV -+#undef MSC_CFG_MAC -+#undef MSC_CFG_L2C -+#undef MSC_CFG_REDUCED_REG -+#undef MSC_CFG_NOD -+#undef MSC_CFG_AUDIO -+#undef MSC_CFG_AUDIO_NONE -+#undef MSC_CFG_IFC -+#undef MSC_CFG_MCU -+#undef MSC_CFG_EX9IT -+#undef MSC_CFG_MSC_EXT -+ -+#undef MSC_CFG2_DSPPF -+#undef MSC_CFG2_ZOL -+ -+#undef MMU_CFG_DE -+ -+#ifdef __cplusplus -+} -+#endif //#ifdef __cplusplus -+ -+#endif //end of _NDS32_ELF_CHECK -+ -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/nds32_ksyms.c linux-3.4.113/arch/nds32/kernel/nds32_ksyms.c ---- linux-3.4.113.orig/arch/nds32/kernel/nds32_ksyms.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/nds32_ksyms.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,103 @@ -+/* -+ * arch/nds32/kernel/nds32_ksyms.c -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+/* -+ * libgcc functions - functions that are used internally by the -+ * compiler... (prototypes are not correct though, but that -+ * doesn't really matter since they're not versioned). -+ */ -+extern void __ashldi3(void); -+extern void __ashrdi3(void); -+extern void __divsi3(void); -+extern void __lshrdi3(void); -+extern void __modsi3(void); -+extern void __muldi3(void); -+extern void __ucmpdi2(void); -+extern void __udivdi3(void); -+extern void __umoddi3(void); -+extern void __udivmoddi4(void); -+extern void __udivsi3(void); -+extern void __umodsi3(void); -+ -+/* -+ * This has a special calling convention; it doesn't -+ * modify any of the usual registers, except for LR. -+ */ -+#define EXPORT_SYMBOL_ALIAS(sym,orig) \ -+ const struct kernel_symbol __ksymtab_##sym \ -+ __attribute__((section("__ksymtab"))) = \ -+ { (unsigned long)&orig, #sym }; -+ -+/* -+ * floating point math emulator support. -+ * These symbols will never change their calling convention... -+ */ -+ -+/* networking */ -+EXPORT_SYMBOL(csum_partial); -+EXPORT_SYMBOL(csum_partial_copy_nocheck); -+ -+/* string / mem functions */ -+EXPORT_SYMBOL(strchr); -+EXPORT_SYMBOL(strrchr); -+EXPORT_SYMBOL(memset); -+EXPORT_SYMBOL(memcpy); -+EXPORT_SYMBOL(memmove); -+EXPORT_SYMBOL(__memzero); -+ -+/* user mem (segment) */ -+EXPORT_SYMBOL(__arch_copy_from_user); -+EXPORT_SYMBOL(__arch_copy_to_user); -+EXPORT_SYMBOL(__arch_clear_user); -+EXPORT_SYMBOL(__arch_strnlen_user); -+EXPORT_SYMBOL(__arch_strncpy_from_user); -+ -+EXPORT_SYMBOL(__get_user_1); -+EXPORT_SYMBOL(__get_user_2); -+EXPORT_SYMBOL(__get_user_4); -+EXPORT_SYMBOL(__get_user_8); -+ -+EXPORT_SYMBOL(__put_user_1); -+EXPORT_SYMBOL(__put_user_2); -+EXPORT_SYMBOL(__put_user_4); -+EXPORT_SYMBOL(__put_user_8); -+ -+/* gcc lib functions */ -+EXPORT_SYMBOL(__ashldi3); -+EXPORT_SYMBOL(__ashrdi3); -+EXPORT_SYMBOL(__divsi3); -+EXPORT_SYMBOL(__lshrdi3); -+EXPORT_SYMBOL(__modsi3); -+EXPORT_SYMBOL(__muldi3); -+EXPORT_SYMBOL(__ucmpdi2); -+EXPORT_SYMBOL(__udivdi3); -+EXPORT_SYMBOL(__umoddi3); -+EXPORT_SYMBOL(__udivmoddi4); -+EXPORT_SYMBOL(__udivsi3); -+EXPORT_SYMBOL(__umodsi3); -+ -+/* syscalls */ -+EXPORT_SYMBOL(sys_write); -+EXPORT_SYMBOL(sys_lseek); -+EXPORT_SYMBOL(sys_exit); -+EXPORT_SYMBOL(sys_wait4); -+ -+/* cache handling */ -+ -+EXPORT_SYMBOL(cpu_icache_inval_all); -+EXPORT_SYMBOL(cpu_dcache_wbinval_all); -+EXPORT_SYMBOL(cpu_dma_inval_range); -+EXPORT_SYMBOL(cpu_dma_wb_range); -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/proc.c linux-3.4.113/arch/nds32/kernel/proc.c ---- linux-3.4.113.orig/arch/nds32/kernel/proc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/proc.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,81 @@ -+/* -+ * linux/arch/nds32/kernel/setup.c -+ * -+ * Copyright (C) 1995-2001 Russell King -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/* ============================================================================ -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for Andes NDS32 architecture. -+ * -+ * Revision History: -+ * -+ * Jul.05.2007 Initial ported by Tom, revised and patched for KGDB -+ * by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+ -+#include -+ -+struct proc_info_item info_item = { -+ "AndesCore", -+#ifndef CONFIG_CPU_ICACHE_DISABLE -+ "I" -+#endif -+#ifndef CONFIG_CPU_DCACHE_DISABLE -+ "D" -+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -+ "(wt)" -+#else -+ "(wb)" -+#endif -+#endif -+}; -+ -+struct proc_info_list n10_proc_info -+ __attribute__ ((section(".proc.info.init"))) = { -+.cpu_val = 0x0a000000,.cpu_mask = 0xff000000,.arch_name = -+ "NDS32 N10",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = -+ &info_item,}; -+ -+struct proc_info_list n12_proc_info -+ __attribute__ ((section(".proc.info.init"))) = { -+.cpu_val = 0x0c000000,.cpu_mask = 0xff000000,.arch_name = -+ "NDS32 N12",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = -+ &info_item,}; -+ -+struct proc_info_list n13_proc_info -+ __attribute__ ((section(".proc.info.init"))) = { -+.cpu_val = 0x0d000000,.cpu_mask = 0xff000000,.arch_name = -+ "NDS32 N13",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = -+ &info_item,}; -+ -+struct proc_info_list n968_proc_info -+ __attribute__ ((section(".proc.info.init"))) = { -+.cpu_val = 0x19000000,.cpu_mask = 0xff000000,.arch_name = -+ "NDS32 N968",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = -+ &info_item,}; -+ -+struct proc_info_list n1068_proc_info -+ __attribute__ ((section(".proc.info.init"))) = { -+.cpu_val = 0x1a000000,.cpu_mask = 0xff000000,.arch_name = -+ "NDS32 N1068",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = -+ &info_item,}; -+ -+// the last one (a roust way to do so) -+struct proc_info_list nXX_proc_info -+ __attribute__ ((section(".proc.info.init"))) = { -+.cpu_val = 0x00000000,.cpu_mask = 0x00000000,.arch_name = -+ "NDS32 N??",.elf_name = "NDS32 ELF",.elf_hwcap = 0,.info = -+ &info_item,}; -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/process.c linux-3.4.113/arch/nds32/kernel/process.c ---- linux-3.4.113.orig/arch/nds32/kernel/process.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/process.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,630 @@ -+/* -+ * linux/arch/nds32/kernel/process.c -+ */ -+/* Copyright (C) 1996-2000 Russell King - Converted to ARM. -+ * Original Copyright (C) 1995 Linus Torvalds -+ * -+ * 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. -+ */ -+/* ============================================================================ -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is process implementation for NDS32 architecture, and it -+ * is original referred from ARM. -+ * -+ * Revision History: -+ * -+ * Oct.02.2007 Initial ported by Tom, Shawn, Steven, and Harry. -+ * Oct.03.2007 Updated get_wchan() for info under /proc. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern const char *processor_modes[]; -+extern void setup_mm_for_reboot(char mode); -+extern struct task_struct *_switch(struct task_struct *last, -+ struct thread_info *prev, -+ struct thread_info *next); -+ -+#ifndef CONFIG_UNLAZY_FPU -+struct task_struct *last_task_used_math = NULL; -+#endif -+#ifndef CONFIG_UNLAZY_AUDIO -+struct task_struct *last_task_used_audio = NULL; -+#endif -+static volatile int hlt_counter; -+ -+#ifdef CONFIG_PROC_FS -+struct proc_dir_entry *proc_dir_cpu; -+EXPORT_SYMBOL(proc_dir_cpu); -+#endif -+ -+extern inline void arch_reset(char mode) -+{ -+ if (mode == 's') { -+ /* Use cpu handler, jump to 0 */ -+ cpu_reset(0); -+ } else { -+ /* -+ * Suppose there should be HW function. -+ * Here we used one tick watchdog as a trick. -+ * It is not very good idea in the view of SoC -+ * design, but smart in firmware functionality. -+ * Harry@Jan,08.2008 -+ */ -+ REG32(WDT_FTWDT010_0_VA_BASE + 0x0C) = 0; // WdCR -+ REG32(WDT_FTWDT010_0_VA_BASE + 0x04) = 1; // WdLoad -+ REG32(WDT_FTWDT010_0_VA_BASE + 0x08) = 0x5AB9; // WdRestart -+ REG32(WDT_FTWDT010_0_VA_BASE + 0x0C) = 0x13; // Go... -+ } -+} -+ -+#ifndef arch_idle -+static inline void arch_idle(void) -+{ -+ cpu_do_idle(); -+} -+#endif -+ -+void disable_hlt(void) -+{ -+ hlt_counter++; -+} -+ -+EXPORT_SYMBOL(disable_hlt); -+ -+void enable_hlt(void) -+{ -+ hlt_counter--; -+} -+ -+EXPORT_SYMBOL(enable_hlt); -+ -+static int __init nohlt_setup(char *__unused) -+{ -+ hlt_counter = 1; -+ return 1; -+} -+ -+static int __init hlt_setup(char *__unused) -+{ -+ hlt_counter = 0; -+ return 1; -+} -+ -+__setup("nohlt", nohlt_setup); -+__setup("hlt", hlt_setup); -+ -+/* -+ * The following aren't currently used. -+ */ -+ -+void (*pm_idle) (void) = NULL; -+EXPORT_SYMBOL(pm_idle); -+ -+void (*pm_power_off) (void); -+EXPORT_SYMBOL(pm_power_off); -+ -+/* -+ * This is our default idle handler. We need to disable -+ * interrupts here to ensure we don't miss a wakeup call. -+ */ -+void default_idle(void) -+{ -+ local_irq_disable(); -+ if (!need_resched() && !hlt_counter) -+ arch_idle(); -+ local_irq_enable(); -+} -+ -+/* -+ * The idle thread. We try to conserve power, while trying to keep -+ * overall latency low. The architecture specific idle is passed -+ * a value to indicate the level of "idleness" of the system. -+ */ -+void cpu_idle(void) -+{ -+ -+ /* endless idle loop with no priority at all */ -+ while (1) { -+ void (*idle) (void) = pm_idle; -+ -+ if (!idle) -+ idle = default_idle; -+ tick_nohz_idle_enter(); -+ leds_event(led_idle_start); -+ while (!need_resched()) -+ idle(); -+ leds_event(led_idle_end); -+ tick_nohz_idle_exit(); -+ preempt_enable_no_resched(); -+ schedule(); -+ preempt_disable(); -+ } -+} -+ -+static char reboot_mode = 'h'; -+ -+int __init reboot_setup(char *str) -+{ -+ reboot_mode = str[0]; -+ return 1; -+} -+ -+#ifdef CONFIG_PLAT_AG102 -+static int cpub_pwroff(void) -+{ -+ //PCU_SET_REG(PCS9_PARA, -+ // PCU_PREPARE(PCS9_PARA, IE, 0x0) | -+ // PCU_PREPARE(PCS9_PARA, CMD, PCS_CMD_SCALING) | -+ // PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | -+ // PCU_PREPARE(PCS9_PARA, NXTPAR, 0x1b) // turn off cpub power -+ //); -+ //printk("cpub Power off: ok!!!OKOKOK\n"); -+ //REG32(PCU_VA_BASE + 0x1A4) = (0x0000001B & 0x00FFFFFF)| ((0x2 << 24) & 0x0F000000) | ((0x1 << 28) & 0x70000000) | 0x00000000; -+ //__asm__ volatile ("standby wait_done\n"); -+ //PCU_SET_REG(PCS9_ST1, 0x0); // clear status -+ //REG32(PCU_VA_BASE + 0x1A8) = 0x0; -+ -+ //par = PCS_POWER_CPUB; -+ //PCU_SET_REG(PCS9_PARA, -+ //PCU_PREPARE(PCS9_PARA, IE, 0x1) | -+ //PCU_PREPARE(PCS9_PARA, CMD, PCS_CMD_PW_DOWN) | -+ //PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | -+ //PCU_PREPARE(PCS9_PARA, NXTPAR, 0x6) // turn off all power -+ -+ //printk("cpua Power off: ok!!!YAYAYA\n"); -+ //printk("The value = 0x%08x\n", (0x00000006 & 0x00FFFFFF)| ((0x1 << 24) & 0x0F000000) | ((0x2 << 28) & 0x70000000) | 0x80000000); -+ REG32(PCU_VA_BASE + 0x1A4) = -+ (0x00000006 & 0x00FFFFFF) | ((0x1 << 24) & 0x0F000000) | -+ ((0x2 << 28) & 0x70000000) | 0x80000000; -+ __asm__ volatile ("standby wake_grant\n"); -+ return (0); -+} -+#else -+static int cpub_pwroff(void) -+{ -+ return 0; -+} -+ -+#endif -+ -+__setup("reboot=", reboot_setup); -+ -+void machine_halt(void) -+{ -+ //ADD by river 2011.04.14 -+ cpub_pwroff(); -+} -+ -+EXPORT_SYMBOL(machine_halt); -+ -+void machine_power_off(void) -+{ -+ if (pm_power_off) -+ pm_power_off(); -+} -+ -+EXPORT_SYMBOL(machine_power_off); -+ -+void machine_restart(char *__unused) -+{ -+ /* -+ * Clean and disable cache, and turn off interrupts -+ */ -+ cpu_proc_fin(); -+ -+ /* -+ * Tell the mm system that we are going to reboot - -+ * we may need it to insert some 1:1 mappings so that -+ * soft boot works. -+ */ -+ setup_mm_for_reboot(reboot_mode); -+ -+ /* -+ * Now call the architecture specific reboot code. -+ */ -+ arch_reset(reboot_mode); -+ -+ /* -+ * Whoops - the architecture was unable to reboot. -+ * Tell the user! -+ */ -+ mdelay(1000); -+ printk("Reboot failed -- System halted\n"); -+ while (1) ; -+} -+ -+EXPORT_SYMBOL(machine_restart); -+ -+void show_regs(struct pt_regs *regs) -+{ -+ print_symbol("PC is at %s\n", instruction_pointer(regs)); -+ print_symbol("LR is at %s\n", regs->NDS32_lp); -+ printk("pc : [<%08lx>] lp : [<%08lx>] %s\n" -+ "sp : %08lx fp : %08lx gp : %08lx\n", -+ instruction_pointer(regs), -+ regs->NDS32_lp, print_tainted(), regs->NDS32_sp, -+ regs->NDS32_fp, regs->NDS32_gp); -+ printk("r25: %08lx r24 : %08lx\n", regs->NDS32_r25, regs->NDS32_r24); -+ -+ printk("r23: %08lx r22: %08lx r21: %08lx r20: %08lx\n", -+ regs->NDS32_r23, regs->NDS32_r22, -+ regs->NDS32_r21, regs->NDS32_r20); -+ printk("r19: %08lx r18: %08lx r17: %08lx r16: %08lx\n", -+ regs->NDS32_r19, regs->NDS32_r18, -+ regs->NDS32_r17, regs->NDS32_r16); -+ printk("r15: %08lx r14: %08lx r13: %08lx r12: %08lx\n", -+ regs->NDS32_r15, regs->NDS32_r14, -+ regs->NDS32_r13, regs->NDS32_r12); -+ printk("r11: %08lx r10: %08lx r9 : %08lx r8 : %08lx\n", -+ regs->NDS32_r11, regs->NDS32_r10, -+ regs->NDS32_r9, regs->NDS32_r8); -+ printk("r7 : %08lx r6 : %08lx r5 : %08lx r4 : %08lx\n", -+ regs->NDS32_r7, regs->NDS32_r6, regs->NDS32_r5, regs->NDS32_r4); -+ printk("r3 : %08lx r2 : %08lx r1 : %08lx r0 : %08lx\n", -+ regs->NDS32_r3, regs->NDS32_r2, regs->NDS32_r1, regs->NDS32_r0); -+ printk(" IRQs o%s Segment %s\n", -+ interrupts_enabled(regs) ? "n" : "ff", -+ segment_eq(get_fs(), get_ds())? "kernel" : "user"); -+} -+ -+void show_fpregs(struct user_fp *regs) -+{ -+ int i; -+ -+ for (i = 0; i < 8; i++) { -+ unsigned long *p; -+ char type; -+ -+ p = (unsigned long *)(regs->fpregs + i); -+ -+ switch (regs->ftype[i]) { -+ case 1: -+ type = 'f'; -+ break; -+ case 2: -+ type = 'd'; -+ break; -+ case 3: -+ type = 'e'; -+ break; -+ default: -+ type = '?'; -+ break; -+ } -+ if (regs->init_flag) -+ type = '?'; -+ -+ printk(" f%d(%c): %08lx %08lx %08lx%c", -+ i, type, p[0], p[1], p[2], i & 1 ? '\n' : ' '); -+ } -+ -+ printk("FPSR: %08lx FPCR: %08lx\n", -+ (unsigned long)regs->fpsr, (unsigned long)regs->fpcr); -+} -+ -+/* -+ * Task structure and kernel stack allocation. -+ */ -+static unsigned long *thread_info_head; -+static unsigned int nr_thread_info; -+ -+#define EXTRA_TASK_STRUCT 4 -+#define ll_alloc_task_struct() ((struct thread_info *) __get_free_pages(GFP_KERNEL,1)) -+#define ll_free_task_struct(p) free_pages((unsigned long)(p),1) -+ -+struct thread_info *alloc_thread_info(struct task_struct *task) -+{ -+ struct thread_info *thread = NULL; -+ -+ if (EXTRA_TASK_STRUCT) { -+ unsigned long *p = thread_info_head; -+ -+ if (p) { -+ thread_info_head = (unsigned long *)p[0]; -+ nr_thread_info -= 1; -+ } -+ thread = (struct thread_info *)p; -+ } -+ -+ if (!thread) -+ thread = ll_alloc_task_struct(); -+ -+#ifdef CONFIG_MAGIC_SYSRQ -+ /* -+ * The stack must be cleared if you want SYSRQ-T to -+ * give sensible stack usage information -+ */ -+ if (thread) { -+ char *p = (char *)thread; -+ memzero(p + KERNEL_STACK_SIZE, KERNEL_STACK_SIZE); -+ } -+#endif -+ return thread; -+} -+ -+void free_thread_info(struct thread_info *thread) -+{ -+ if (EXTRA_TASK_STRUCT && nr_thread_info < EXTRA_TASK_STRUCT) { -+ unsigned long *p = (unsigned long *)thread; -+ p[0] = (unsigned long)thread_info_head; -+ thread_info_head = p; -+ nr_thread_info += 1; -+ } else -+ ll_free_task_struct(thread); -+} -+ -+/* -+ * Free current thread data structures etc.. -+ */ -+void exit_thread(void) -+{ -+#if defined(CONFIG_FPU) -+# ifndef CONFIG_UNLAZY_FPU -+ if (last_task_used_math == current) { -+ last_task_used_math = NULL; -+ } -+# endif -+#endif -+#if defined(CONFIG_AUDIO) -+# ifndef CONFIG_UNLAZY_AUDIO -+ if (last_task_used_audio == current) { -+ last_task_used_audio = NULL; -+ } -+# endif -+#endif -+} -+ -+void flush_thread(void) -+{ -+ struct task_struct *tsk = current; -+ -+ memset(&tsk->thread.debug, 0, sizeof(struct debug_info)); -+#if defined(CONFIG_FPU) -+ clear_fpu(task_pt_regs(tsk)); -+ clear_used_math(); -+# ifndef CONFIG_UNLAZY_FPU -+ if (last_task_used_math == current) { -+ last_task_used_math = NULL; -+ } -+# endif -+#endif -+ -+#if defined(CONFIG_AUDIO) -+ clear_audio(task_pt_regs(tsk)); -+ clear_tsk_thread_flag(tsk, TIF_USEDAUDIO); -+# ifndef CONFIG_UNLAZY_AUDIO -+ if (last_task_used_audio == current) { -+ last_task_used_audio = NULL; -+ } -+# endif -+#endif -+ -+} -+ -+void release_thread(struct task_struct *dead_task) -+{ -+} -+ -+asmlinkage void ret_from_fork(void) __asm__("ret_from_fork"); -+ -+/* -+ * Shuffle the argument into the correct register before calling the -+ * thread function. $r1 is the thread argument, $r2 is the pointer to -+ * the thread function, and $r3 points to the exit function. -+ */ -+extern void kernel_thread_helper(void); -+asm(".section .text\n" -+ " .align\n" -+ " .type kernel_thread_helper, #function\n" -+ "kernel_thread_helper:\n" -+ " move $r2, $lp\n" -+ " move $r0, $r1\n" -+ " move $lp, $r3\n" -+ " jr $r2 \n" -+ " .size kernel_thread_helper, . - kernel_thread_helper\n" -+ " .previous"); -+ -+pid_t kernel_thread(int (*fn) (void *), void *arg, unsigned long flags) -+{ -+ struct pt_regs regs; -+ -+ memset(®s, 0, sizeof(regs)); -+ -+ regs.NDS32_r1 = (unsigned long)arg; -+ regs.NDS32_r2 = (unsigned long)fn; -+ /* to apply right path */ -+ regs.NDS32_lp = regs.NDS32_r2; -+ regs.NDS32_r3 = (unsigned long)do_exit; -+ regs.NDS32_ipc = (unsigned long)kernel_thread_helper; -+ -+#ifdef __NDS32_EB__ -+#define PSW_DE PSW_mskBE -+#else -+#define PSW_DE 0x0 -+#endif -+ -+#ifdef CONFIG_WBNA -+#define PSW_valWBNA PSW_mskWBNA -+#else -+#define PSW_valWBNA 0x0 -+#endif -+ -+ regs.NDS32_ipsw = -+ (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | -+ PSW_SYSTEM | PSW_INTL_1 | PSW_mskGIE); -+ regs.NDS32_ir0 = -+ (PSW_CPL_ANY | PSW_valWBNA | PSW_mskDT | PSW_mskIT | PSW_DE | -+ PSW_SYSTEM | PSW_INTL_1); -+ -+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, 0, ®s, 0, NULL, -+ NULL); -+} -+ -+EXPORT_SYMBOL(kernel_thread); -+ -+int -+copy_thread(unsigned long clone_flags, unsigned long stack_start, -+ unsigned long stk_sz, struct task_struct *p, struct pt_regs *regs) -+{ -+ struct thread_info *thread = task_thread_info(p); -+ struct pt_regs *childregs; -+ -+ childregs = -+ ((struct pt_regs *)((unsigned long)thread + THREAD_SIZE - 8)) - 1; -+ -+ *childregs = *regs; -+ childregs->NDS32_r0 = 0; /* child get zero as ret. */ -+ childregs->NDS32_sp = stack_start; -+ childregs->NDS32_osp = 0; -+ -+ thread->sp_save = ((struct cpu_context_save *)(childregs)) - 1; -+ /* cpu context switching */ -+ thread->sp_save->pc = (unsigned long)ret_from_fork; -+ if (clone_flags & CLONE_SETTLS) -+ childregs->NDS32_r25 = regs->NDS32_r3; -+ -+#ifdef CONFIG_FPU -+ if (used_math()) { -+# ifdef CONFIG_UNLAZY_FPU -+ unlazy_fpu(current); -+# else -+ preempt_disable(); -+ if (last_task_used_math == current) -+ save_fpu(current); -+ preempt_enable(); -+# endif -+ p->thread.fpu = current->thread.fpu; -+ clear_fpu(task_pt_regs(p)); -+ set_stopped_child_used_math(p); -+ } -+#endif -+ -+#ifdef CONFIG_AUDIO -+ if (test_tsk_thread_flag(current, TIF_USEDAUDIO)) { -+# ifdef CONFIG_UNLAZY_AUDIO -+ unlazy_audio(current); -+# else -+ preempt_disable(); -+ if (last_task_used_audio == current) -+ save_audio(current); -+ preempt_enable(); -+# endif -+ p->thread.audio = current->thread.audio; -+ clear_audio(childregs); -+ set_tsk_thread_flag(p, TIF_USEDAUDIO); -+ } -+#endif -+ -+#ifdef CONFIG_HWZOL -+ childregs->NDS32_lb = 0; -+ childregs->NDS32_le = 0; -+ childregs->NDS32_lc = 0; -+#endif -+ -+ return 0; -+} -+ -+struct task_struct *__switch_to(struct task_struct *last, -+ struct thread_info *prev, -+ struct thread_info *next) -+{ -+#if defined(CONFIG_FPU) || defined(CONFIG_AUDIO) -+# ifdef CONFIG_UNLAZY_FPU -+ unlazy_fpu(prev->task); -+# endif -+# ifdef CONFIG_UNLAZY_AUDIO -+ unlazy_audio(prev->task); -+# endif -+ if (!(next->task->flags & PF_KTHREAD)) { -+#ifdef CONFIG_FPU -+ clear_fpu(task_pt_regs(next->task)); -+#endif -+#ifdef CONFIG_AUDIO -+ clear_audio(task_pt_regs(next->task)); -+#endif -+ } -+#endif -+ return _switch(last, prev, next); -+} -+ -+/* -+ * fill in the fpe structure for a core dump... -+ */ -+int dump_fpu(struct pt_regs *regs, elf_fpregset_t * fpu) -+{ -+ int fpvalid = 0; -+ -+#if 0 // XXX defined(CONFIG_FPU) -+ struct task_struct *tsk = current; -+ -+ fpvalid = !!tsk_used_math(tsk); -+ if (fpvalid) { -+ unlazy_fpu(tsk, regs); -+ memcpy(fpu, &tsk->thread.fpu, sizeof(*fpu)); -+ } -+#endif -+ -+ return fpvalid; -+} -+ -+EXPORT_SYMBOL(dump_fpu); -+ -+unsigned long get_wchan(struct task_struct *p) -+{ -+ unsigned long fp, lr; -+ unsigned long stack_start, stack_end; -+ int count = 0; -+ -+ if (!p || p == current || p->state == TASK_RUNNING) -+ return 0; -+ -+#ifdef CONFIG_FRAME_POINTER -+ stack_start = (unsigned long)end_of_stack(p); -+ stack_end = (unsigned long)task_stack_page(p) + THREAD_SIZE; -+ -+ fp = thread_saved_fp(p); -+ do { -+ if (fp < stack_start || fp > stack_end) -+ return 0; -+ lr = ((unsigned long *)fp)[0]; -+ if (!in_sched_functions(lr)) -+ return lr; -+ fp = *(unsigned long *)(fp + 4); -+ } while (count++ < 16); -+ return 0; -+#else -+ return 0; -+#endif -+} -+ -+EXPORT_SYMBOL(get_wchan); -+ -+extern int do_elf_check_arch(const struct elf32_hdr *hdr); -+ -+int elf_check_arch(const struct elf32_hdr *hdr) -+{ -+ return do_elf_check_arch(hdr); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/ptrace.c linux-3.4.113/arch/nds32/kernel/ptrace.c ---- linux-3.4.113.orig/arch/nds32/kernel/ptrace.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/ptrace.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,919 @@ -+/* -+ * linux/arch/nds32/kernel/ptrace.c -+ */ -+/* By Ross Biro 1/23/92 -+ * edited by Linus Torvalds -+ * ARM modifications Copyright (C) 2000 Russell King -+ * NDS32 modifications Copyright (C) 2007 Harry Pan -+ * -+ * 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. -+ */ -+/* ============================================================================ -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for Andes NDS32 architecture. -+ * -+ * Revision History: -+ * -+ * Jul.31.2007 Initial ported by Tom, Shawn, and Steven, -+ * revised by Harry. -+ * Current implmentation is based on Andes Instruction -+ * Set Architecture Specification (AS-0001-0001) -+ * version:3.7 date:7-20-2007. -+ * It is original taken from ARM, then fit to NDS32. -+ * Aug.15.2007 Mainly updated breakpoint handling base on NDS32 ISA. -+ * I also did code revise. -+ * Nov.14.2007 Fixed up ptrace_set_bpt() while handling 16-bit insn. -+ * Nov.27.2007 Added checking duplicate breakpoints in -+ * add_breakpoint(), based on Shawn's idea. -+ * Dec.06.2007 Added get_user_gpr(). -+ * Apr.17.2009 Added support for FPU and Audio regs. -+ * Added support for PTRACE_GETFPREGS, PTRACE_SETFPREGS, -+ * PTRACE_GETAUREGS, PTRACE_SETAUREGS -+ * -+ * Note: -+ * -+ * Current layout: 0-31 GR, 32-34 SPR, 35-... SR, index start from zero. -+ * -+ * +----------+-----+--------------+---+--------+ -+ * | GR | SPR | SR |...| Audio | -+ * +----------+-----+--------------+---+--------+ -+ * 0 32 35 ...500 531 -+ * -+ * ============================================================================ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ptrace.h" -+ -+#ifdef __NDS32_EL__ -+#define BREAKINST 0x01EA -+#else -+#define BREAKINST 0xEA01 -+#endif -+ -+/* get_user_reg() -+ * -+ * This routine will get a word off of the processes privileged stack. -+ * the offset is how far from the base addr as stored in the THREAD. -+ * this routine assumes that all the privileged stacks are in our -+ * data space. -+ */ -+static inline unsigned int get_user_reg(struct task_struct *task, int offset) -+{ -+ return task_pt_regs(task)->uregs[offset]; -+} -+ -+#if !defined(CONFIG_HSS) -+/* get_user_gpr() -+ * -+ */ -+static unsigned int get_user_gpr(struct task_struct *task, int idx) -+{ -+ unsigned int ret; -+ -+ if (idx < 26) // r0 to r25 -+ ret = get_user_reg(task, idx + 13); -+ else if (idx == 26 || idx == 27) // p0, p1 -+ ret = get_user_reg(task, idx - 26 + 7); -+ else if (idx > 27 && idx < 31) // fp, gp, lp -+ ret = get_user_reg(task, idx + 11); -+ else if (idx == 31) // sp -+ ret = get_user_reg(task, 3); -+ else -+ ret = 0; -+ -+ return ret; -+} -+#endif -+ -+/* put_user_reg() -+ * -+ * this routine will put a word on the processes privileged stack. -+ * the offset is how far from the base addr as stored in the THREAD. -+ * this routine assumes that all the privileged stacks are in our -+ * data space. -+ */ -+static inline int put_user_reg(struct task_struct *task, int offset, long data) -+{ -+ struct pt_regs newregs, *regs = task_pt_regs(task); -+ int ret = -EINVAL; -+ -+ newregs = *regs; -+ newregs.uregs[offset] = data; -+ -+ if (valid_user_regs(&newregs)) { -+ regs->uregs[offset] = data; -+ ret = 0; -+ } -+ -+ return ret; -+} -+ -+#if !defined(CONFIG_HSS) -+/* -+ * Read instruction. -+ */ -+static inline int -+read_insn(struct task_struct *task, unsigned long addr, u32 * res) -+{ -+ int ret; -+ *res = 0; -+ ret = access_process_vm(task, addr, res, 2, 0); -+ if (ret != 2) -+ return 0; -+#ifdef __NDS32_EL__ -+ *res = swab16(*res); -+#endif -+ if ((*res) & 0x8000) -+ return 2; -+ -+ ret = access_process_vm(task, addr, res, 4, 0); -+ if (ret != 4) -+ return 0; -+#ifdef __NDS32_EL__ -+ *res = swab32(*res); -+#endif -+ return 4; -+} -+ -+/* get_branch_address() -+ * -+ * Decode branch instructions and destination. -+ */ -+static unsigned long -+get_branch_address(struct task_struct *child, -+ unsigned long pc, unsigned long insn, unsigned int size) -+{ -+ unsigned int tpc = 0; -+ -+ /* -+ * TODO: COLE -+ * would it be simpler if we use two BREAKs, -+ * one for take, one for not -+ */ -+ -+ if (size == 4) { -+ /* 32-bit instruction */ -+ if ((insn & 0x7e000000) == 0x4c000000) // BR1 -+ { -+ int cond, imm14s; -+ unsigned int rt, ra; -+ -+ rt = (insn >> 20) & 0x1f; -+ ra = (insn >> 15) & 0x1f; -+ cond = (insn >> 14) & 0x01; -+ imm14s = insn & 0x00003fff; -+ -+ if (imm14s & 0x00002000) // sign extend -+ imm14s -= (0x00002000 << 1); -+ -+ rt = get_user_gpr(child, rt); -+ ra = get_user_gpr(child, ra); -+ -+ if (((cond == 1) && (rt != ra)) || // bne -+ ((cond == 0) && (rt == ra))) // beq -+ tpc = pc + (imm14s << 1); -+ } else if ((insn & 0x7e000000) == 0x4e000000) // BR2 -+ { -+ int cond, imm16s, taken = 0; -+ int rt; -+ -+ rt = (insn >> 20) & 0x1f; -+ cond = (insn >> 16) & 0x0f; -+ imm16s = insn & 0x0000ffff; -+ -+ if (imm16s & 0x00008000) // sign extend -+ imm16s -= (0x00008000 << 1); -+ -+ rt = get_user_gpr(child, rt); -+ -+ switch (cond) { -+ case 0x02: // beqz -+ if (rt == 0) -+ taken = 1; -+ break; -+ case 0x03: // bnez -+ if (rt != 0) -+ taken = 1; -+ break; -+ case 0x06: // bgtz -+ if (rt > 0) -+ taken = 1; -+ break; -+ case 0x07: // blez -+ if (rt <= 0) -+ taken = 1; -+ break; -+ case 0x04: // bgez -+ case 0x0c: // bgezal -+ if (rt >= 0) -+ taken = 1; -+ break; -+ case 0x05: // bltz -+ case 0x0d: // bltzal -+ if (rt < 0) -+ taken = 1; -+ break; -+ default: -+ printk(KERN_WARNING -+ "ptrace: unknown conditional branch.\n"); -+ break; -+ } -+ -+ if (taken) -+ tpc = pc + (imm16s << 1); -+ } else if ((insn & 0x7e000000) == 0x48000000) // JI -+ { -+ int imm24s; -+ -+ imm24s = insn & 0x00ffffff; -+ -+ if (imm24s & 0x00800000) // sign extend -+ imm24s -= (0x00800000 << 1); -+ -+ tpc = pc + (imm24s << 1); -+ } else if ((insn & 0x7e000000) == 0x4a000000) // JREG -+ { -+ unsigned int rb = (insn >> 10) & 0x1f; -+ -+ tpc = get_user_gpr(child, rb); -+ } -+ -+ } else { -+ /* 16-bit instruction */ -+ -+ if ((insn & 0xf800) == 0xc000) // beqz38 -+ { -+ unsigned int rt3; -+ -+ rt3 = (insn >> 8) & 0x07; -+ -+ rt3 = get_user_gpr(child, rt3); -+ -+ if (rt3 == 0) { -+ int imm8s; -+ -+ imm8s = insn & 0x00ff; -+ -+ if (imm8s & 0x0080) // sign extend -+ imm8s -= (0x0080 << 1); -+ -+ tpc = pc + (imm8s << 1); -+ } -+ } -+ -+ if ((insn & 0xf800) == 0xc800) // bnez38 -+ { -+ unsigned int rt3; -+ -+ rt3 = (insn >> 8) & 0x07; -+ -+ rt3 = get_user_gpr(child, rt3); -+ -+ if (rt3 != 0) { -+ int imm8s; -+ -+ imm8s = insn & 0x00ff; -+ -+ if (imm8s & 0x0080) // sign extend -+ imm8s -= (0x0080 << 1); -+ -+ tpc = pc + (imm8s << 1); -+ } -+ } -+ -+ if ((insn & 0xf800) == 0xd000) // beqs38, j8 -+ { -+ unsigned int rt3, r5; -+ -+ rt3 = (insn >> 8) & 0x07; -+ -+ rt3 = get_user_gpr(child, rt3); -+ r5 = get_user_gpr(child, 5); -+ -+ if (r5 == rt3) { -+ int imm8s; -+ imm8s = insn & 0x00ff; -+ -+ if (imm8s & 0x0080) // sign extend -+ imm8s -= (0x0080 << 1); -+ -+ tpc = pc + (imm8s << 1); -+ } -+ } -+ -+ if ((insn & 0xf800) == 0xd800) // bnes38 -+ { -+ unsigned int rt3, r5; -+ -+ rt3 = (insn >> 8) & 0x07; -+ -+ r5 = get_user_gpr(child, 5); -+ rt3 = get_user_gpr(child, rt3); -+ -+ if (r5 != rt3) { -+ int imm8s; -+ -+ imm8s = insn & 0x00ff; -+ -+ if (imm8s & 0x0080) // sign extend -+ imm8s -= (0x0080 << 1); -+ -+ tpc = pc + (imm8s << 1); -+ } -+ } -+ -+ if ((insn & 0xffe0) == 0xdd00 || // jr5 -+ (insn & 0xffe0) == 0xdd80 || // ret5 -+ (insn & 0xffe0) == 0xdd20) // jral5 -+ { -+ unsigned int rb5; -+ -+ rb5 = insn & 0x1f; -+ -+ tpc = get_user_gpr(child, rb5); -+ } -+ -+ if ((insn & 0xfe00) == 0xe800) { -+ int taken = 0; -+ unsigned int r15; -+ -+ r15 = get_user_gpr(child, 15); -+ -+ if (insn & 0x0100) // bnezs8 -+ { -+ if (r15 != 0) -+ taken = 1; -+ } else // beqzs8 -+ { -+ if (r15 == 0) -+ taken = 1; -+ } -+ -+ if (taken) { -+ int imm8s; -+ -+ imm8s = insn & 0x00ff; -+ -+ if (imm8s & 0x0080) // sign extend -+ imm8s -= (0x0080 << 1); -+ -+ tpc = pc + (imm8s << 1); -+ } -+ } -+ } -+ -+ return tpc; -+} -+ -+/* -+ * Swap instructions in the user program. -+ * swap in new_insn. save orignal value in old_insn -+ * assume new_insn is 2-bytes long -+ */ -+static int -+swap_insn(struct task_struct *task, unsigned long addr, -+ u16 * old_insn, u16 * new_insn) -+{ -+ int ret; -+ -+ ret = access_process_vm(task, addr, old_insn, 2, 0); -+ if (ret == 2) -+ ret = access_process_vm(task, addr, new_insn, 2, 1); -+ -+ return ret; -+} -+ -+/* -+ * Add one breakpoint in the user program. -+ */ -+static void -+add_breakpoint(struct task_struct *task, struct debug_info *dbg, -+ unsigned long addr) -+{ -+ u16 new_insn = BREAKINST; -+ int res; -+ -+ if (dbg->valid) { -+ printk(KERN_ERR "ptrace: too many breakpoints\n"); -+ return; -+ } -+ -+ dbg->address = addr; -+ res = swap_insn(task, addr, &dbg->insn, &new_insn); -+ if (res == 2) -+ dbg->valid = 1; -+ if (!dbg->valid) -+ printk(KERN_ERR "ptrace: fail to add breakpoint\n"); -+} -+ -+/* -+ * Clear one software breakpoint in the user program. -+ */ -+static void clear_breakpoint(struct task_struct *task, struct debug_info *dbg) -+{ -+ int ret; -+ unsigned int addr = dbg->address; -+ u16 old_insn; -+ -+ if (!dbg->valid) { -+ return; -+ } -+ dbg->valid = 0; -+ -+ ret = swap_insn(task, addr, &old_insn, &dbg->insn); -+ -+ if (ret != 2 || old_insn != BREAKINST) { -+ printk(KERN_ERR "ptrace: %s:%d: corrupted NDS16 breakpoint at " -+ "0x%08x (0x%04x)\n", task->comm, task->pid, -+ addr, old_insn); -+ } -+} -+ -+/* -+ * ptrace_set_swbk -+ * Set breakpoint in user program. -+ */ -+void ptrace_set_swbk(struct task_struct *child) -+{ -+ struct pt_regs *regs; -+ unsigned long pc; -+ unsigned int size; -+ u32 insn; -+ -+ /* -+ * always clear before set, -+ * since in some sepcial case, it may fail to hit -+ */ -+ ptrace_cancel_swbk(child); -+ regs = task_pt_regs(child); -+ pc = instruction_pointer(regs); -+ size = read_insn(child, pc, &insn); -+ -+ printk(KERN_DEBUG " STEP.size=%d\n", size); -+ -+ if (size > 0) { -+ struct debug_info *dbg = &child->thread.debug; -+ unsigned int tpc; -+ -+ /* Predict next PC. */ -+ tpc = get_branch_address(child, pc, insn, size); -+ -+ if (tpc) { -+ printk(KERN_DEBUG " STEP.addr=0x%x\n", tpc); -+ add_breakpoint(child, dbg, tpc); -+ } else { -+ if (size == 4) { -+ printk(KERN_DEBUG " STEP.addr=0x%x\n", -+ (unsigned int)(pc + 4)); -+ add_breakpoint(child, dbg, pc + 4); -+ } else if (size == 2) { -+ printk(KERN_DEBUG " STEP.addr=0x%x\n", -+ (unsigned int)(pc + 2)); -+ add_breakpoint(child, dbg, pc + 2); -+ } else { -+ printk(KERN_ERR -+ "ptrace: bad step address, pc + %d\n", -+ size); -+ } -+ } -+ } -+} -+ -+/* -+ * Ensure no single-step breakpoint is pending. Returns non-zero -+ * value if child was being single-stepped. -+ */ -+void ptrace_cancel_swbk(struct task_struct *child) -+{ -+ if (!child->thread.debug.valid) { -+ return; -+ } -+ -+ clear_breakpoint(child, &child->thread.debug); -+} -+#endif /* end of !defined (CONFIG_HSS) */ -+ -+/* -+ * Called by kernel/ptrace.c when detaching.. -+ * -+ * Make sure the single step bit is not set. -+ */ -+void ptrace_disable(struct task_struct *child) -+{ -+ user_disable_single_step(child); -+} -+ -+/* -+ * Handle hitting a breakpoint. -+ */ -+void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, -+ int error_code, int si_code) -+{ -+ struct siginfo info; -+ -+#if !defined (CONFIG_HSS) -+ /* clear the swbk; otherwise the user will see it */ -+ ptrace_cancel_swbk(tsk); -+#endif -+ -+ tsk->thread.trap_no = 1; -+ tsk->thread.error_code = error_code; -+ -+ memset(&info, 0, sizeof(info)); -+ info.si_signo = SIGTRAP; -+ info.si_code = si_code; -+ -+ info.si_addr = (void __user *)instruction_pointer(regs); -+ -+ /* Send us the fake SIGTRAP */ -+ force_sig_info(SIGTRAP, &info, tsk); -+} -+ -+/* ptrace_read_user() -+ * -+ * Read the word at offset "off" into the "struct user". We -+ * actually access the pt_regs stored on the kernel stack. -+ */ -+static int -+ptrace_read_user(struct task_struct *tsk, unsigned long off, -+ unsigned long __user * ret) -+{ -+ unsigned long tmp = 0; -+ -+ if (off < 500) { -+ if (off & 3 || off >= sizeof(struct user)) -+ return -EIO; -+ -+ if (off < sizeof(struct pt_regs)) -+ tmp = get_user_reg(tsk, off >> 2); -+ -+ return put_user(tmp, ret); -+ } else if (off < 532) { -+#ifdef CONFIG_AUDIO -+ off -= 500; -+ if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { -+#ifdef CONFIG_UNLAZY_AUDIO -+ unlazy_audio(tsk); -+#else -+ preempt_disable(); -+ if (last_task_used_audio == tsk) -+ save_audio(tsk); -+ preempt_enable(); -+#endif -+ tmp = tsk->thread.audio.auregs[off]; -+ } -+#endif -+ return put_user(tmp, ret); -+ } else -+ return -EIO; -+} -+ -+/* ptrace_write_user() -+ * -+ * Write the word at offset "off" into "struct user". We -+ * actually access the pt_regs stored on the kernel stack. -+ */ -+static int -+ptrace_write_user(struct task_struct *tsk, unsigned long off, unsigned long val) -+{ -+ if (off < 500) { -+ if (off & 3 || off >= sizeof(struct user)) -+ return -EIO; -+ -+ if (off >= sizeof(struct pt_regs)) -+ return 0; -+ -+ return put_user_reg(tsk, off >> 2, val); -+ } else if (off < 532) { -+#ifdef CONFIG_AUDIO -+ off -= 500; -+ if (!test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { -+ /* First time Audio user. */ -+ memset(&tsk->thread.audio, 0, -+ sizeof(struct audio_struct)); -+ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); -+ } else { -+#ifdef CONFIG_UNLAZY_AUDIO -+ unlazy_audio(tsk); -+#else -+ if (last_task_used_audio == tsk) { -+ preempt_disable(); -+ save_audio(tsk); -+ preempt_enable(); -+ } -+#endif -+ /* Let the lazy mechanism do the restore. */ -+ clear_audio(task_pt_regs(tsk)); -+ } -+ tsk->thread.audio.auregs[off] = val; -+#endif -+ return 0; -+ } else -+ return -EIO; -+} -+ -+/* ptrace_getregs() -+ * -+ * Get all user integer registers. -+ */ -+static int ptrace_getregs(struct task_struct *tsk, void __user * uregs) -+{ -+ struct pt_regs *regs = task_pt_regs(tsk); -+ -+ return copy_to_user(uregs, regs, sizeof(struct pt_regs)) ? -EFAULT : 0; -+} -+ -+/* ptrace_setregs() -+ * -+ * Set all user integer registers. -+ */ -+static int ptrace_setregs(struct task_struct *tsk, void __user * uregs) -+{ -+ struct pt_regs newregs; -+ int ret; -+ -+ ret = -EFAULT; -+ if (copy_from_user(&newregs, uregs, sizeof(struct pt_regs)) == 0) { -+ struct pt_regs *regs = task_pt_regs(tsk); -+ -+ ret = -EINVAL; -+ if (valid_user_regs(&newregs)) { -+ *regs = newregs; -+ ret = 0; -+ } -+ } -+ -+ return ret; -+} -+ -+/* ptrace_getfpregs() -+ * -+ * Get the child FPU state. -+ */ -+static int ptrace_getfpregs(struct task_struct *tsk, void __user * ufpregs) -+{ -+#ifdef CONFIG_FPU -+ if (used_math()) { -+# ifdef CONFIG_UNLAZY_FPU -+ unlazy_fpu(tsk); -+# else -+ preempt_disable(); -+ if (last_task_used_math == tsk) -+ save_fpu(tsk); -+ preempt_enable(); -+# endif -+ return copy_to_user(ufpregs, &tsk->thread.fpu, -+ sizeof(struct fpu_struct)) ? -EFAULT : 0; -+ } else { -+ /* First time FPU user. */ -+ memset(ufpregs, -1, sizeof(struct fpu_struct)); -+ return 0; -+ } -+ -+#else -+ return -EFAULT; -+#endif -+} -+ -+/* -+ * Set the child FPU state. -+ */ -+static int ptrace_setfpregs(struct task_struct *tsk, void __user * ufpregs) -+{ -+#ifdef CONFIG_FPU -+ int ret; -+ -+# ifndef CONFIG_UNLAZY_FPU -+ if (last_task_used_math == tsk) -+# endif -+ clear_fpu(task_pt_regs(tsk)); -+ -+ ret = -+ copy_from_user(&tsk->thread.fpu, ufpregs, -+ sizeof(struct fpu_struct)) ? -EFAULT : 0; -+ -+ if (!ret && !used_math()) { -+ /* First time Audio user. */ -+ set_used_math(); -+ } -+ -+ return ret; -+#else -+ return -EFAULT; -+#endif -+} -+ -+/* ptrace_getauregs() -+ * -+ * Get the child Audio state. -+ */ -+static int ptrace_getauregs(struct task_struct *tsk, void __user * uauregs) -+{ -+#ifdef CONFIG_AUDIO -+ if (test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { -+#ifdef CONFIG_UNLAZY_AUDIO -+ unlazy_audio(tsk); -+#else -+ preempt_disable(); -+ if (last_task_used_audio == tsk) -+ save_audio(tsk); -+ preempt_enable(); -+#endif -+ return copy_to_user(uauregs, &tsk->thread.audio, -+ sizeof(struct audio_struct)) ? -EFAULT : 0; -+ } else { -+ /* First time Audio user. */ -+ memset(uauregs, 0, sizeof(struct audio_struct)); -+ return 0; -+ } -+ -+#else -+ return -EFAULT; -+#endif -+} -+ -+/* -+ * Set the child Audio state. -+ */ -+static int ptrace_setauregs(struct task_struct *tsk, void __user * uauregs) -+{ -+#ifdef CONFIG_AUDIO -+ int ret; -+ -+#ifdef CONFIG_UNLAZY_AUDIO -+ clear_audio(task_pt_regs(tsk)); -+#else -+ if (last_task_used_audio == tsk) -+ clear_audio(task_pt_regs(tsk)); -+#endif -+ ret = -+ copy_from_user(&tsk->thread.audio, uauregs, -+ sizeof(struct audio_struct)) ? -EFAULT : 0; -+ -+ if (!ret && !test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) { -+ /* First time Audio user. */ -+ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); -+ } -+ -+ return ret; -+#else -+ return -EFAULT; -+#endif -+} -+ -+/* do_ptrace() -+ * -+ * Provide ptrace defined service. -+ */ -+long arch_ptrace(struct task_struct *child, long request, unsigned long addr, -+ unsigned long data) -+{ -+ int ret; -+ -+ switch (request) { -+ case PTRACE_PEEKUSR: -+ ret = -+ ptrace_read_user(child, addr, (unsigned long __user *)data); -+ break; -+ -+ case PTRACE_POKEUSR: -+ ret = ptrace_write_user(child, addr, data); -+ break; -+ -+ case PTRACE_GETREGS: -+ ret = ptrace_getregs(child, (void __user *)data); -+ break; -+ -+ case PTRACE_SETREGS: -+ ret = ptrace_setregs(child, (void __user *)data); -+ break; -+ -+ case PTRACE_GETFPREGS: -+ ret = ptrace_getfpregs(child, (void __user *)data); -+ break; -+ -+ case PTRACE_SETAUREGS: -+ ret = ptrace_setauregs(child, (void __user *)data); -+ break; -+ -+ case PTRACE_GETAUREGS: -+ ret = ptrace_getauregs(child, (void __user *)data); -+ break; -+ -+ case PTRACE_SETFPREGS: -+ ret = ptrace_setfpregs(child, (void __user *)data); -+ break; -+/* -+ case PTRACE_GET_THREAD_AREA: -+ ret = put_user(task_thread_info(child)->tp_value, -+ (unsigned long __user *) data); -+ break; -+*/ -+ -+ default: -+ ret = ptrace_request(child, request, addr, data); -+ break; -+ } -+ -+ return ret; -+} -+ -+void user_enable_single_step(struct task_struct *child) -+{ -+ struct pt_regs *regs; -+ regs = task_pt_regs(child); -+#ifdef CONFIG_HSS -+ regs->NDS32_ipsw |= PSW_mskHSS; -+#else -+ ptrace_set_swbk(child); -+#endif -+ set_tsk_thread_flag(child, TIF_SINGLESTEP); -+} -+ -+void user_disable_single_step(struct task_struct *child) -+{ -+ struct pt_regs *regs; -+ regs = task_pt_regs(child); -+#ifdef CONFIG_HSS -+ regs->NDS32_ipsw &= ~PSW_mskHSS; -+#else -+ ptrace_cancel_swbk(child); -+#endif -+ clear_tsk_thread_flag(child, TIF_SINGLESTEP); -+} -+ -+/* sys_trace() -+ * -+ * syscall trace handler. -+ */ -+static inline void do_syscall_trace(void) -+{ -+ if (!test_thread_flag(TIF_SYSCALL_TRACE)) -+ return; -+ if (!(current->ptrace & PT_PTRACED)) -+ return; -+ -+ /* the 0x80 provides a way for the tracing parent to distinguish -+ between a syscall stop and SIGTRAP delivery */ -+ ptrace_notify(SIGTRAP | ((current->ptrace & PT_TRACESYSGOOD) -+ ? 0x80 : 0)); -+ /* -+ * this isn't the same as continuing with a signal, but it will do -+ * for normal use. strace only continues with a signal if the -+ * stopping signal is not SIGTRAP. -brl -+ */ -+ if (current->exit_code) { -+ send_sig(current->exit_code, current, 1); -+ current->exit_code = 0; -+ } -+} -+ -+asmlinkage int syscall_trace_enter(int syscall, struct pt_regs *regs) -+{ -+ int orig_r0; -+ -+ orig_r0 = regs->NDS32_ORIG_r0; -+ regs->NDS32_ORIG_r0 = syscall; -+ do_syscall_trace(); -+ syscall = regs->NDS32_ORIG_r0; -+ regs->NDS32_ORIG_r0 = orig_r0; -+ return syscall & 0xfff; -+} -+ -+asmlinkage void syscall_trace_leave(struct pt_regs *regs) -+{ -+ do_syscall_trace(); -+ -+ /* synthsize a single-step */ -+#if !defined(CONFIG_HSS) -+ /* for SWBK, break should be remove */ -+ ptrace_cancel_swbk(current); -+#endif -+ if (test_thread_flag(TIF_SINGLESTEP)) { -+ printk(KERN_INFO "synthsize trap (tf=0x%0x\n", -+ (unsigned int)current_thread_info()->flags); -+ send_sigtrap(current, regs, 0, TRAP_BRKPT); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/ptrace.h linux-3.4.113/arch/nds32/kernel/ptrace.h ---- linux-3.4.113.orig/arch/nds32/kernel/ptrace.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/ptrace.h 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,48 @@ -+/* -+ * linux/arch/nds32/kernel/ptrace.h -+ */ -+/* Copyright (C) 2000-2003 Russell King -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/* ============================================================================ -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for Andes NDS32 architecture. -+ * -+ * Revision History: -+ * -+ * Jul.31.2007 Initial ported by Tom, Shawn, and Steven, -+ * revised by Harry. -+ * Current implmentation is based on Andes Instruction -+ * Set Architecture Specification (AS-0001-0001) -+ * version:3.7 date:7-20-2007. -+ * It is original taken from ARM, then fit to NDS32. -+ * -+ * Note: -+ * -+ * Current layout: 0-31 GR, 32-34 SPR, 35-... SR, index start from zero. -+ * -+ * +----------+-----+--------------+ -+ * | GR | SPR | SR | -+ * +-------------------------------+ -+ * 0 32 35 ... -+ * -+ * ============================================================================ -+ */ -+#ifndef __KERNEL_PTRACE_H__ -+#define __KERNEL_PTRACE_H__ -+ -+extern void ptrace_cancel_swbk(struct task_struct *); -+extern void ptrace_set_swbk(struct task_struct *); -+extern void ptrace_break(struct task_struct *, struct pt_regs *); -+extern void send_sigtrap(struct task_struct *tsk, struct pt_regs *regs, -+ int error_code, int si_code); -+ -+#endif // __KERNEL_PTRACE_H__ -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/relocate_kernel.S linux-3.4.113/arch/nds32/kernel/relocate_kernel.S ---- linux-3.4.113.orig/arch/nds32/kernel/relocate_kernel.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/relocate_kernel.S 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,89 @@ -+/* -+ * relocate_kernel.S - put the kernel image in place to boot -+ */ -+ -+#include -+ -+ .globl relocate_new_kernel -+relocate_new_kernel: -+ la $r0, kexec_indirection_page -+ slli $r0, $r0, 2 -+ srli $r0, $r0, 2 -+ lwi $r0, [$r0] -+ la $r1, kexec_start_address -+ slli $r1, $r1, 2 -+ srli $r1, $r1, 2 -+ lwi $r1, [$r1] -+ -+0: /* top, read another word for the indirection page */ -+ lwi.bi $r3, [$r0], #4 -+ -+ /* Is it a destination page. Put destination address to r4 */ -+ andi $p0, $r3, #1 -+ beqz $p0, 1f -+ li $p0, ~#1 -+ and $r4, $r3, $p0 -+ b 0b -+1: -+ /* Is it an indirection page */ -+ andi $p0, $r3, #2 -+ beqz $p0, 1f -+ li $p0, ~#2 -+ and $r0, $r3, $p0 -+ b 0b -+1: -+ /* are we done ? */ -+ andi $p0, $r3, #4 -+ beqz $p0, 1f -+ b 2f -+1: -+ /* is it source ? */ -+ andi $p0, $r3, #8 -+ beqz $p0, 0b -+ li $p0, ~#8 -+ and $r3, $r3, $p0 -+ li $r6, #(1024/16) /* 16 words per loop */ -+9: -+ lmw.bim $r7, [$r3], $r22 -+ smw.bim $r7, [$r4], $r22 -+ addi $r6, $r6, -1 -+ bnez $r6, 9b -+ b 0b -+2: -+ /* Jump to relocated kernel */ -+ move $lp, $r1 -+ li $r0, 0 -+ la $r1, kexec_mach_type -+ slli $r1, $r1, 2 -+ srli $r1, $r1, 2 -+ lwi $r1, [$r1] -+ la $r2, kexec_boot_atags -+ slli $r2, $r2, 2 -+ srli $r2, $r2, 2 -+ lwi $r2, [$r2] -+ ret -+ -+ .globl kexec_start_address -+kexec_start_address: -+ .long 0x0 -+ -+ .globl kexec_indirection_page -+kexec_indirection_page: -+ .long 0x0 -+ -+ .globl kexec_mach_type -+kexec_mach_type: -+ .long 0x0 -+ -+ /* phy addr of the atags for the new kernel */ -+ .globl kexec_boot_atags -+kexec_boot_atags: -+ .long 0x0 -+ -+relocate_new_kernel_end: -+ -+ .globl relocate_new_kernel_size -+relocate_new_kernel_size: -+ .long relocate_new_kernel_end - relocate_new_kernel -+ -+ -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/setup.c linux-3.4.113/arch/nds32/kernel/setup.c ---- linux-3.4.113.orig/arch/nds32/kernel/setup.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/setup.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,1049 @@ -+/* -+ * linux/arch/nds32/kernel/setup.c -+ * -+ * Copyright (C) 1995-2001 Russell King -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/* ============================================================================ -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for Andes NDS32 architecture. -+ * -+ * Revision History: -+ * -+ * Jul.05.2007 Initial ported by Tom, revised and patched for KGDB -+ * by Harry. -+ * Aug.26.2008 Some reworks on CPU info output for SMP. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#ifndef MEM_SIZE -+#define MEM_SIZE CONFIG_SDRAM_SIZE -+#endif -+ -+#ifndef RAMDISK_SIZE -+#define RAMDISK_SIZE CONFIG_BLK_DEV_RAM_SIZE -+#endif -+ -+extern void (*init_arch_irq) (void); -+ -+extern void paging_init(struct machine_desc *desc); -+extern void reboot_setup(char *str); -+extern int root_mountflags; -+extern unsigned long _stext, _text, _etext, _sdata, _edata, _end; -+extern unsigned int ag101_cpufreq_get(unsigned int dummy); -+ -+unsigned long cpu_id, cpu_rev, cpu_cfgid; -+char *endianness = NULL; -+ -+unsigned int __machine_arch_type; -+EXPORT_SYMBOL(__machine_arch_type); -+ -+unsigned int elf_hwcap; -+EXPORT_SYMBOL(elf_hwcap); -+ -+unsigned char aux_device_present; -+ -+char elf_platform[ELF_PLATFORM_SIZE]; -+EXPORT_SYMBOL(elf_platform); -+ -+unsigned long phys_initrd_start __initdata = 0; -+unsigned long phys_initrd_size __initdata = 0; -+ -+static struct meminfo meminfo __initdata = { 0, }; -+ -+static const char *machine_name; -+static struct proc_info_item proc_info; -+static char command_line[COMMAND_LINE_SIZE]; -+ -+struct machine_desc *machine_desc __initdata; -+ -+static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; -+ -+DEFINE_PER_CPU(struct cpuinfo_nds32, cpu_data); -+ -+/* -+ * Standard memory resources -+ */ -+static struct resource mem_res[] = { -+ { -+ .name = "Video RAM", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_MEM}, -+ { -+ .name = "Kernel text", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_MEM}, -+ { -+ .name = "Kernel data", -+ .start = 0, -+ .end = 0, -+ .flags = IORESOURCE_MEM} -+}; -+ -+#define video_ram mem_res[0] -+#define kernel_code mem_res[1] -+#define kernel_data mem_res[2] -+ -+static struct resource io_res[] = { -+ { -+ .name = "reserved", -+ .start = 0x3bc, -+ .end = 0x3be, -+ .flags = IORESOURCE_IO | IORESOURCE_BUSY}, -+ { -+ .name = "reserved", -+ .start = 0x378, -+ .end = 0x37f, -+ .flags = IORESOURCE_IO | IORESOURCE_BUSY}, -+ { -+ .name = "reserved", -+ .start = 0x278, -+ .end = 0x27f, -+ .flags = IORESOURCE_IO | IORESOURCE_BUSY} -+}; -+ -+#define lp0 io_res[0] -+#define lp1 io_res[1] -+#define lp2 io_res[2] -+ -+/* -+ * The following string table, must sync with HWCAP_xx bitmask, -+ * which is defined in -+ */ -+static const char *hwcap_str[] = { -+ "mfusr_pc", -+ "perf1", -+ "perf2", -+ "fpu", -+ "audio", -+ "16b", -+ "string", -+ "reduced_regs", -+ "video", -+ "encrypt", -+ "edm", -+ "lmdma", -+ "pfm", -+ "hsmp", -+ "trace", -+ "div", -+ "mac", -+ "l2c", -+ "dx_regs", -+ "v2", -+ NULL, -+}; -+ -+static void __init squash_mem_tags(struct tag *tag) -+{ -+ for (; tag->hdr.size; tag = tag_next(tag)) -+ if (tag->hdr.tag == ATAG_MEM) -+ tag->hdr.tag = ATAG_NONE; -+} -+ -+struct cache_info L1_cache_info[2]; -+ -+static void __init dump_cpu_info(int cpu) -+{ -+ int i = 0, aliasing_num; -+#ifdef CONFIG_CACHE_L2 -+ unsigned long l2set, l2way, l2clsz; -+#endif -+ printk("CPU%d Features: ", cpu); -+ -+ for (i = 0; hwcap_str[i]; i++) { -+ if (elf_hwcap & (1 << i)) -+ printk("%s ", hwcap_str[i]); -+ } -+ -+ printk("\n"); -+ -+ L1_cache_info[ICACHE].cache_type = ICACHE; -+ L1_cache_info[ICACHE].ways = CACHE_WAY(ICACHE); -+ L1_cache_info[ICACHE].way_bits = ilog2(CACHE_WAY(ICACHE)); -+ L1_cache_info[ICACHE].line_size = CACHE_LINE_SIZE(ICACHE); -+ L1_cache_info[ICACHE].line_bits = ilog2(CACHE_LINE_SIZE(ICACHE)); -+ L1_cache_info[ICACHE].sets = CACHE_SET(ICACHE); -+ L1_cache_info[ICACHE].set_bits = ilog2(CACHE_SET(ICACHE)); -+ L1_cache_info[ICACHE].size = -+ CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) * CACHE_LINE_SIZE(ICACHE) / -+ 1024; -+ printk("L1I:%dKB/%dS/%dW/%dB\n", L1_cache_info[ICACHE].size, -+ L1_cache_info[ICACHE].sets, L1_cache_info[ICACHE].ways, -+ L1_cache_info[ICACHE].line_size); -+ aliasing_num = -+ L1_cache_info[ICACHE].size * 1024 / PAGE_SIZE / -+ L1_cache_info[ICACHE].ways; -+ if (aliasing_num & 1 && aliasing_num != 1) -+ printk -+ ("%s: not alising:%d, it should be multiple of 2 if it ia aliasing cache.\n", -+ __func__, aliasing_num); -+ L1_cache_info[ICACHE].aliasing_num = aliasing_num; -+ L1_cache_info[ICACHE].aliasing_mask = (aliasing_num - 1) << PAGE_SHIFT; -+ L1_cache_info[ICACHE].not_aliasing_mask = -+ ~L1_cache_info[ICACHE].aliasing_mask; -+ L1_cache_info[DCACHE].cache_type = DCACHE; -+ L1_cache_info[DCACHE].ways = CACHE_WAY(DCACHE); -+ L1_cache_info[DCACHE].way_bits = ilog2(CACHE_WAY(DCACHE)); -+ L1_cache_info[DCACHE].line_size = CACHE_LINE_SIZE(DCACHE); -+ L1_cache_info[DCACHE].line_bits = ilog2(CACHE_LINE_SIZE(DCACHE)); -+ L1_cache_info[DCACHE].sets = CACHE_SET(DCACHE); -+ L1_cache_info[DCACHE].set_bits = ilog2(CACHE_SET(DCACHE)); -+ L1_cache_info[DCACHE].size = -+ CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) * CACHE_LINE_SIZE(DCACHE) / -+ 1024; -+ printk("L1D:%dKB/%dS/%dW/%dB\n", L1_cache_info[DCACHE].size, -+ L1_cache_info[DCACHE].sets, L1_cache_info[DCACHE].ways, -+ L1_cache_info[DCACHE].line_size); -+ aliasing_num = -+ L1_cache_info[DCACHE].size * 1024 / PAGE_SIZE / -+ L1_cache_info[DCACHE].ways; -+#ifdef CONFIG_HIGHMEM -+ if (aliasing_num > 1 && CONFIG_HIGHMEM) -+ WARN(1, -+ "%s: HIGHMEM is not supported for alising VIPT cache. aliasing_num:%d\n", -+ __func__, aliasing_num); -+#else -+ if (aliasing_num & 1 && aliasing_num != 1) -+ printk -+ ("%s: not alising:%d, it should be multiple of 2 if it ia aliasing cache.\n", -+ __func__, aliasing_num); -+#endif -+ L1_cache_info[DCACHE].aliasing_num = aliasing_num; -+ L1_cache_info[DCACHE].aliasing_mask = (aliasing_num - 1) << PAGE_SHIFT; -+ L1_cache_info[DCACHE].not_aliasing_mask = -+ ~L1_cache_info[DCACHE].aliasing_mask; -+#ifdef CONFIG_CPU_DCACHE_WRITETHROUGH -+ printk("L1 D-Cache is WRITE-THROUGH\n"); -+#else -+ printk("L1 D-Cache is WRITE-BACK\n"); -+#endif -+ -+ -+#ifdef CONFIG_CACHE_L2 -+ /* Here translation is on but I/O address is not mapped yet. */ -+ SET_PSW(GET_PSW() & ~PSW_mskDT); -+ DSB(); -+ l2set = -+ 64 << ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2SET) >> -+ L2_CA_CONF_offL2SET); -+ l2way = -+ 1 + -+ ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2WAY) >> -+ L2_CA_CONF_offL2WAY); -+ l2clsz = -+ 4 << ((inl(L2CC_PA_BASE + L2_CA_CONF_OFF) & L2_CA_CONF_mskL2CLSZ) >> -+ L2_CA_CONF_offL2CLSZ); -+ SET_PSW(GET_PSW() | PSW_mskDT); -+ DSB(); -+ -+ printk("L2:%luKB/%luS/%luW/%luB\n", -+ l2set * l2way * l2clsz / 1024, l2set, l2way, l2clsz); -+#endif -+#ifdef CONFIG_FPU -+ /* Disable fpu and enable when it is used. */ -+ disable_fpu(); -+ printk("FPU is able to use.\n"); -+#endif -+} -+ -+static void __init setup_processor(void) -+{ -+ unsigned long tmp = 0; -+ struct proc_info_list *list; -+ extern struct proc_info_list __proc_info_begin, __proc_info_end; -+ -+ register unsigned coreid = GET_CPU_VER(); -+ for (list = &__proc_info_begin; list < &__proc_info_end; list++) -+// if (list->cpu_val == (GET_CPU_VER() & CPU_VER_mskCPUID)) -+ if (list->cpu_val == (coreid & list->cpu_mask)) -+ break; -+ /* -+ * If the architecture type is not recognised, then we -+ * can co nothing... -+ */ -+ if (list >= &__proc_info_end) { -+ printk -+ ("Processor configuration botched (CPU_VER 0x%lx), unable to continue.\n", -+ GET_CPU_VER()); -+ while (1) ; -+ } -+ -+ proc_info = *list->info; -+ -+ cpu_dcache_inval_all(); // XXX head.S turn $$ on, need change. -+ cpu_icache_inval_all(); -+ DSB(); -+ ISB(); -+ -+ cpu_id = GET_CPU_ID(); -+ cpu_rev = GET_CPU_REV(); -+ cpu_cfgid = GET_CPU_CFGID(); -+ -+ printk("CPU: %s, %s %s, CPU_VER 0x%08lx(id %lu, rev %lu, cfg %lu)\n", -+ list->arch_name, -+ proc_info.manufacturer, proc_info.cpu_name, -+ GET_CPU_VER(), cpu_id, cpu_rev, cpu_cfgid); -+ -+ elf_hwcap |= HWCAP_MFUSR_PC; -+ -+ if (((GET_MSC_CFG() & MSC_CFG_mskBASEV) >> MSC_CFG_offBASEV) == 0) { -+ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) -+ elf_hwcap &= ~HWCAP_MFUSR_PC; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskDIV) -+ elf_hwcap |= HWCAP_DIV; -+ -+ if ((GET_MSC_CFG() & MSC_CFG_mskMAC) -+ || (cpu_id == 12 && cpu_rev < 4)) -+ elf_hwcap |= HWCAP_MAC; -+ } else { -+ elf_hwcap |= HWCAP_V2; -+ elf_hwcap |= HWCAP_DIV; -+ elf_hwcap |= HWCAP_MAC; -+ } -+ -+ if (cpu_cfgid & 0x0001) -+ elf_hwcap |= HWCAP_EXT; -+ -+ if (cpu_cfgid & 0x0002) -+ elf_hwcap |= HWCAP_BASE16; -+ -+ if (cpu_cfgid & 0x0004) -+ elf_hwcap |= HWCAP_EXT2; -+ -+ if (cpu_cfgid & 0x0008) -+ elf_hwcap |= HWCAP_FPU; -+ -+ if (cpu_cfgid & 0x0010) -+ elf_hwcap |= HWCAP_STRING; -+ -+ if (GET_MMU_CFG() & MMU_CFG_mskDE) -+ endianness = "MSB"; -+ else -+ endianness = "LSB"; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskEDM) -+ elf_hwcap |= HWCAP_EDM; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskLMDMA) -+ elf_hwcap |= HWCAP_LMDMA; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskPFM) -+ elf_hwcap |= HWCAP_PFM; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskHSMP) -+ elf_hwcap |= HWCAP_HSMP; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskTRACE) -+ elf_hwcap |= HWCAP_TRACE; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskAUDIO) -+ elf_hwcap |= HWCAP_AUDIO; -+ -+ if (GET_MSC_CFG() & MSC_CFG_mskL2C) -+ elf_hwcap |= HWCAP_L2C; -+ -+#ifdef CONFIG_ANDES_PAGE_SIZE_4KB -+ if (CPU_IS_N1213_43U1HA0()) { -+ /* -+ * Downsize dcache to bypass N1213-43u1h inconsistent -+ * use of PA and VA in fill-buffer logic issue. -+ */ -+ -+ if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096) -+ tmp |= 0x02 << SDZ_CTL_offDCDZ; -+ -+ if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096) -+ tmp |= 0x02 << SDZ_CTL_offICDZ; -+ -+ SET_SDZ_CTL(tmp); -+ ISB(); -+ printk("CPU%i enabled dcache downsizing to half set/4-way.\n", -+ smp_processor_id()); -+ } -+#endif /* CONFIG_ANDES_PAGE_SIZE_4KB */ -+ -+#ifdef CONFIG_CACHE_L2 -+#ifdef CONFIG_PLAT_AG102 -+ SET_HSMP_SADDR((CPU_MEM_PA_BASE & HSMP_SADDR_mskSADDR) | -+ (0xC00 << HSMP_SADDR_offRANGE) | HSMP_SADDR_mskEN); -+#endif -+ -+ /* Here translation is on but I/O address is not mapped yet. */ -+ SET_PSW(GET_PSW() & ~PSW_mskDT); -+ DSB(); -+ -+ /* This is the time when we enable L2$. */ -+ /* All masters can't write another master register */ -+ tmp = inl(L2CC_PA_BASE + L2CC_PROT_OFF); -+ tmp &= ~L2CC_PROT_mskMRWEN; -+ outl(tmp, L2CC_PA_BASE + L2CC_PROT_OFF); -+ -+ /* All masters share the whole cache memory space */ -+ tmp = inl(L2CC_PA_BASE + L2CC_SETUP_OFF); -+ tmp &= ~L2CC_SETUP_mskPART; -+ outl(tmp, L2CC_PA_BASE + L2CC_SETUP_OFF); -+ -+ /* each master access self master, does not add master base */ -+ tmp = inl(L2CC_PA_BASE + L2CC_CTRL_OFF); -+ tmp |= L2CC_CTRL_mskEN; -+ outl(tmp, L2CC_PA_BASE + L2CC_CTRL_OFF); -+ -+ SET_PSW(GET_PSW() | PSW_mskDT); -+ ISB(); -+#endif -+ tmp = GET_CACHE_CTL(); -+#ifndef CONFIG_CPU_DCACHE_DISABLE -+ tmp |= CACHE_CTL_mskDC_EN; -+#endif -+ -+#ifndef CONFIG_CPU_ICACHE_DISABLE -+ tmp |= CACHE_CTL_mskIC_EN; -+#endif -+ SET_CACHE_CTL(tmp); -+ DSB(); -+ ISB(); -+ -+ sprintf(elf_platform, "%s %s", list->elf_name, endianness); -+ -+ dump_cpu_info(smp_processor_id()); -+} -+ -+static struct machine_desc *__init setup_machine(unsigned int nr) -+{ -+ struct machine_desc *list; -+ -+ extern struct machine_desc __arch_info_begin, __arch_info_end; -+ /* -+ * locate machine in the list of supported machines. -+ */ -+ for (list = &__arch_info_begin; list < &__arch_info_end; list++) -+ if (list->nr == nr) -+ break; -+ /* -+ * If the architecture type is not recognised, then we -+ * can co nothing... -+ */ -+ if (list >= &__arch_info_end) { -+ printk("Architecture configuration botched (nr 0x%x), unable " -+ "to continue.\n", nr); -+ while (1) ; -+ } -+ -+ printk(KERN_INFO "Machine: %s\n", list->name); -+ -+ return list; -+} -+ -+static void __init early_initrd(char **p) -+{ -+ unsigned long start, size; -+ -+ start = memparse(*p, p); -+ if (**p == ',') { -+ size = memparse((*p) + 1, p); -+ -+ phys_initrd_start = start; //pa -+ phys_initrd_size = size; -+ } -+ printk(KERN_INFO -+ "phys_initrd_start at 0x%08lx, phys_initrd_size:0x%08lx\n", -+ phys_initrd_start, phys_initrd_size); -+ //memblock_reserve(phys_initrd_start, phys_initrd_size); -+} -+ -+__early_param("initrd=", early_initrd); -+ -+/* -+ * Pick out the memory size. We look for mem=size@start, -+ * where start and size are "size[KkMm]" -+ */ -+static void __init early_mem(char **p) -+{ -+ static int usermem __initdata = 0; -+ unsigned long size, start; -+ -+ /* -+ * If the user specifies memory size, we -+ * blow away any automatically generated -+ * size. -+ */ -+ if (usermem == 0) { -+ usermem = 1; -+ meminfo.nr_banks = 0; -+ } -+ -+ start = PHYS_OFFSET; //Tom 0x0 -+ size = memparse(*p, p); -+ if (**p == '@') -+ start = memparse(*p + 1, p); -+ -+ meminfo.bank[meminfo.nr_banks].start = start; -+ meminfo.bank[meminfo.nr_banks].size = size; -+ meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(start); -+ memblock_add_node(meminfo.bank[meminfo.nr_banks].start, -+ meminfo.bank[meminfo.nr_banks].size, 0); -+ meminfo.nr_banks += 1; -+ -+} -+ -+__early_param("mem=", early_mem); -+ -+/* -+ * Initial parsing of the command line. -+ */ -+void __init parse_cmdline(char **cmdline_p, char *from) -+{ -+ char c = ' ', *to = command_line; -+ int len = 0; -+ -+ for (;;) { -+ if (c == ' ') { -+ extern struct early_params __early_begin, __early_end; -+ struct early_params *p; -+ -+ for (p = &__early_begin; p < &__early_end; p++) { -+ int len = strlen(p->arg); -+ -+ if (memcmp(from, p->arg, len) == 0) { -+ if (to != command_line) -+ to -= 1; -+ from += len; -+ p->fn(&from); -+ -+ while (*from != ' ' && *from != '\0') -+ from++; -+ break; -+ } -+ } -+ } -+ c = *from++; -+ if (!c) -+ break; -+ if (COMMAND_LINE_SIZE <= ++len) -+ break; -+ *to++ = c; -+ } -+ *to = '\0'; -+ *cmdline_p = command_line; -+} -+ -+static void __init -+setup_ramdisk(int doload, int prompt, int image_start, unsigned int rd_sz) -+{ -+#ifdef CONFIG_BLK_DEV_RAM -+ extern int rd_size, rd_image_start, rd_prompt, rd_doload; -+ -+ rd_image_start = image_start; -+ rd_prompt = prompt; -+ rd_doload = doload; -+ -+ if (rd_sz) -+ rd_size = rd_sz; -+#endif -+} -+ -+static void __init -+request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) -+{ -+ struct resource *res; -+ int i; -+ -+ kernel_code.start = virt_to_phys(&_text); -+ kernel_code.end = virt_to_phys(&_etext - 1); -+ kernel_data.start = virt_to_phys(&_sdata); -+ kernel_data.end = virt_to_phys(&_end - 1); -+ -+ for (i = 0; i < mi->nr_banks; i++) { -+ unsigned long virt_start, virt_end; -+ -+ if (mi->bank[i].size == 0) -+ continue; -+ -+ virt_start = __phys_to_virt(mi->bank[i].start); -+ virt_end = virt_start + mi->bank[i].size - 1; -+ -+ res = alloc_bootmem_low(sizeof(*res)); -+ res->name = "System RAM"; -+ res->start = __virt_to_phys(virt_start); -+ res->end = __virt_to_phys(virt_end); -+ res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; -+ -+ request_resource(&iomem_resource, res); -+ -+ if (kernel_code.start >= res->start && -+ kernel_code.end <= res->end) -+ request_resource(res, &kernel_code); -+ if (kernel_data.start >= res->start && -+ kernel_data.end <= res->end) -+ request_resource(res, &kernel_data); -+ } -+ -+ if (mdesc->video_start) { -+ video_ram.start = mdesc->video_start; -+ video_ram.end = mdesc->video_end; -+ request_resource(&iomem_resource, &video_ram); -+ } -+ -+ /* -+ * Some machines don't have the possibility of ever -+ * possessing lp0, lp1 or lp2 -+ */ -+ if (mdesc->reserve_lp0) -+ request_resource(&ioport_resource, &lp0); -+ if (mdesc->reserve_lp1) -+ request_resource(&ioport_resource, &lp1); -+ if (mdesc->reserve_lp2) -+ request_resource(&ioport_resource, &lp2); -+} -+ -+/* -+ * Tag parsing. -+ * -+ * This is the new way of passing data to the kernel at boot time. Rather -+ * than passing a fixed inflexible structure to the kernel, we pass a list -+ * of variable-sized tags to the kernel. The first tag must be a ATAG_CORE -+ * tag for the list to be recognised (to distinguish the tagged list from -+ * a param_struct). The list is terminated with a zero-length tag (this tag -+ * is not parsed in any way). -+ */ -+//flag bit 0 = read-only -+static int __init parse_tag_core(const struct tag *tag) -+{ -+ if (tag->hdr.size > 2) { -+ if ((tag->u.core.flags & 1) == 0) -+ root_mountflags &= ~MS_RDONLY; -+ ROOT_DEV = old_decode_dev(tag->u.core.rootdev); -+ } -+ return 0; -+} -+ -+__tagtable(ATAG_CORE, parse_tag_core); -+ -+static int __init parse_tag_mem32(const struct tag *tag) -+{ -+ if (meminfo.nr_banks >= NR_BANKS) { -+ printk(KERN_WARNING -+ "Ignoring memory bank 0x%08x size %dKB\n", -+ tag->u.mem.start, tag->u.mem.size / 1024); -+ return -EINVAL; -+ } -+ meminfo.bank[meminfo.nr_banks].start = tag->u.mem.start; -+ meminfo.bank[meminfo.nr_banks].size = tag->u.mem.size; -+ memblock_add_node(meminfo.bank[meminfo.nr_banks].start, -+ meminfo.bank[meminfo.nr_banks].size, 0); -+ meminfo.bank[meminfo.nr_banks].node = PHYS_TO_NID(tag->u.mem.start); -+ meminfo.nr_banks += 1; -+ -+ return 0; -+} -+ -+__tagtable(ATAG_MEM, parse_tag_mem32); -+ -+#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_DUMMY_CONSOLE) -+struct screen_info screen_info = { -+ .orig_video_lines = 30, -+ .orig_video_cols = 80, -+ .orig_video_mode = 0, -+ .orig_video_ega_bx = 0, -+ .orig_video_isVGA = 1, -+ .orig_video_points = 8 -+}; -+ -+static int __init parse_tag_videotext(const struct tag *tag) -+{ -+ screen_info.orig_x = tag->u.videotext.x; -+ screen_info.orig_y = tag->u.videotext.y; -+ screen_info.orig_video_page = tag->u.videotext.video_page; -+ screen_info.orig_video_mode = tag->u.videotext.video_mode; -+ screen_info.orig_video_cols = tag->u.videotext.video_cols; -+ screen_info.orig_video_ega_bx = tag->u.videotext.video_ega_bx; -+ screen_info.orig_video_lines = tag->u.videotext.video_lines; -+ screen_info.orig_video_isVGA = tag->u.videotext.video_isvga; -+ screen_info.orig_video_points = tag->u.videotext.video_points; -+ return 0; -+} -+ -+__tagtable(ATAG_VIDEOTEXT, parse_tag_videotext); -+#endif -+ -+static int __init parse_tag_ramdisk(const struct tag *tag) -+{ -+ setup_ramdisk((tag->u.ramdisk.flags & 1) == 0, -+ (tag->u.ramdisk.flags & 2) == 0, -+ tag->u.ramdisk.start, tag->u.ramdisk.size); -+ return 0; -+} -+ -+__tagtable(ATAG_RAMDISK, parse_tag_ramdisk); -+ -+static int __init parse_tag_initrd(const struct tag *tag) -+{ -+ printk(KERN_WARNING "ATAG_INITRD is deprecated; " -+ "please update your bootloader.\n"); -+ phys_initrd_start = __virt_to_phys(tag->u.initrd.start); -+ phys_initrd_size = tag->u.initrd.size; -+ return 0; -+} -+ -+__tagtable(ATAG_INITRD, parse_tag_initrd); -+ -+static int __init parse_tag_initrd2(const struct tag *tag) -+{ -+ phys_initrd_start = tag->u.initrd.start; -+ phys_initrd_size = tag->u.initrd.size; -+ return 0; -+} -+ -+__tagtable(ATAG_INITRD2, parse_tag_initrd2); -+ -+static int __init parse_tag_revision(const struct tag *tag) -+{ -+ return 0; -+} -+ -+__tagtable(ATAG_REVISION, parse_tag_revision); -+ -+static int __init parse_tag_cmdline(const struct tag *tag) -+{ -+ strlcpy(default_command_line, tag->u.cmdline.cmdline, -+ COMMAND_LINE_SIZE); -+ return 0; -+} -+ -+__tagtable(ATAG_CMDLINE, parse_tag_cmdline); -+ -+/* -+ * Scan the tag table for this tag, and call its parse function. -+ * The tag table is built by the linker from all the __tagtable -+ * declarations. -+ */ -+static int __init parse_tag(const struct tag *tag) -+{ -+ extern struct tagtable __tagtable_begin, __tagtable_end; -+ struct tagtable *t; -+ -+ for (t = &__tagtable_begin; t < &__tagtable_end; t++) -+ if (tag->hdr.tag == t->tag) { -+ t->parse(tag); -+ break; -+ } -+ -+ return t < &__tagtable_end; -+} -+ -+/* -+ * Parse all tags in the list, checking both the global and architecture -+ * specific tag tables. -+ */ -+static void __init parse_tags(const struct tag *t) -+{ -+ for (; t->hdr.size; t = tag_next(t)) -+ if (!parse_tag(t)) -+ printk(KERN_WARNING -+ "Ignoring unrecognised tag 0x%08x\n", -+ t->hdr.tag); -+} -+ -+/* -+ * This holds our defaults. -+ */ -+static struct init_tags { -+ struct tag_header hdr1; -+ struct tag_core core; -+ struct tag_header hdr2; -+ struct tag_mem32 mem; -+ struct tag_header hdr3; -+} init_tags __initdata = { -+ {tag_size(tag_core), ATAG_CORE}, //hdr1 -+ {0, PAGE_SIZE, 0xff}, -+ {tag_size(tag_mem32), ATAG_MEM}, //hdr2 -+ {MEM_SIZE, PHYS_OFFSET}, -+ {0, ATAG_NONE} -+}; -+ -+static unsigned long __init setup_memory(void) -+{ -+ unsigned long bootmap_size; -+ unsigned long ram_start_pfn; -+ unsigned long free_ram_start_pfn; -+ phys_addr_t memory_start, memory_end; -+ struct memblock_region *region; -+ -+ memory_end = memory_start = 0; -+ -+ /* Find main memory where is the kernel */ -+ for_each_memblock(memory, region) { -+ memory_start = region->base; -+ memory_end = region->base + region->size; -+ printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__, -+ memory_start, memory_end); -+ } -+ -+ if (!memory_end) { -+ panic("No memory!"); -+ } -+ -+ ram_start_pfn = PFN_UP(memblock_start_of_DRAM()); -+ /* free_ram_start_pfn is first page after kernel */ -+ free_ram_start_pfn = PFN_UP(__pa(&_end)); -+ max_pfn = PFN_DOWN(memblock_end_of_DRAM()); -+ -+ /* it could update max_pfn */ -+ if (max_pfn - ram_start_pfn <= MAXMEM_PFN) -+ max_low_pfn = max_pfn; -+ else { -+ max_low_pfn = MAXMEM_PFN + ram_start_pfn; -+#ifndef CONFIG_HIGHMEM -+ max_pfn = MAXMEM_PFN + ram_start_pfn; -+#endif -+ } -+ /* high_memory is related with VMALLOC */ -+ high_memory = (void *)__va(max_low_pfn * PAGE_SIZE); -+ min_low_pfn = free_ram_start_pfn; -+ -+ /* -+ * initialize the boot-time allocator (with low memory only). -+ * -+ * This makes the memory from the end of the kernel to the end of -+ * RAM usable. -+ * init_bootmem sets the global values min_low_pfn, max_low_pfn. -+ */ -+ bootmap_size = init_bootmem_node(NODE_DATA(0), free_ram_start_pfn, -+ ram_start_pfn, max_low_pfn); -+ free_bootmem(PFN_PHYS(free_ram_start_pfn), -+ (max_low_pfn - free_ram_start_pfn) << PAGE_SHIFT); -+ reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size, -+ BOOTMEM_DEFAULT); -+ -+ for_each_memblock(reserved, region) { -+ if (region->size != 0) { -+ printk(KERN_INFO "Reserved - 0x%08x-0x%08x\n", -+ (u32) region->base, (u32) region->size); -+ reserve_bootmem(region->base, region->size, -+ BOOTMEM_DEFAULT); -+ } -+ } -+ return max_low_pfn; -+} -+ -+void __init setup_arch(char **cmdline_p) -+{ -+ struct tag *tags = (struct tag *)&init_tags; -+ struct machine_desc *mdesc; -+ char *from = default_command_line; -+ -+ setup_processor(); -+ mdesc = setup_machine(machine_arch_type); -+ machine_desc = mdesc; -+ machine_name = mdesc->name; -+ -+ if (mdesc->soft_reboot) -+ reboot_setup("s"); -+ -+ if (mdesc->param_offset) -+ tags = phys_to_virt(mdesc->param_offset); -+ -+ if (tags->hdr.tag != ATAG_CORE) -+ tags = (struct tag *)&init_tags; -+ -+ if (tags->hdr.tag == ATAG_CORE) { -+ if (meminfo.nr_banks != 0) -+ squash_mem_tags(tags); -+ parse_tags(tags); -+ } -+ -+ init_mm.start_code = (unsigned long)&_text; -+ init_mm.end_code = (unsigned long)&_etext; -+ init_mm.end_data = (unsigned long)&_edata; -+ init_mm.brk = (unsigned long)&_end; -+ -+ memcpy(boot_command_line, from, COMMAND_LINE_SIZE); -+ boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; -+ parse_cmdline(cmdline_p, from); -+ -+ /* use generic way to parse */ -+ parse_early_param(); -+ -+ /* setup bootmem allocator */ -+ setup_memory(); -+ -+ strlcpy(command_line, from, COMMAND_LINE_SIZE); -+ *cmdline_p = command_line; -+ -+ paging_init(mdesc); -+ request_standard_resources(&meminfo, mdesc); //- for test only -+ -+#ifdef CONFIG_SMP -+ smp_init_cpus(); -+#endif -+ -+ /* -+ * Set up various architecture-specific pointers -+ */ -+ init_arch_irq = mdesc->init_irq; -+ system_timer = mdesc->timer; -+ if (mdesc->init_machine) -+ mdesc->init_machine(); -+ -+#if defined(CONFIG_VT) -+#if defined(CONFIG_VGA_CONSOLE) -+ conswitchp = &vga_con; -+#elif defined(CONFIG_DUMMY_CONSOLE) -+ conswitchp = &dummy_con; //+ Tom: we will reach here -+#endif -+#endif -+ -+ early_trap_init(); -+} -+ -+/* -+ * cpu_init - initialise one CPU. -+ * -+ * cpu_init dumps the cache information, initialises SMP specific -+ * information. -+ */ -+ -+void __init cpu_init(void) -+{ -+ unsigned int cpu = smp_processor_id(), tmp = 0; -+ -+ if (cpu >= NR_CPUS) { -+ printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); -+ BUG(); -+ } -+ -+ if (system_state == SYSTEM_BOOTING) -+ dump_cpu_info(cpu); -+ -+ tmp = 1 << IVB_offESZ; -+#ifdef CONFIG_EVIC -+ tmp |= 1 << IVB_offEVIC; -+#endif -+ SET_IVB(tmp | IVB_BASE); -+ tmp = 0x10003; -+ SET_INT_MASK(tmp); -+ ISB(); -+} -+ -+static int __init topology_init(void) -+{ -+ int cpu; -+ -+ for_each_possible_cpu(cpu) -+ register_cpu(&per_cpu(cpu_data, cpu).cpu, cpu); -+ -+ return 0; -+} -+ -+subsys_initcall(topology_init); -+ -+static int c_show(struct seq_file *m, void *v) -+{ -+ int i; -+ -+ seq_printf(m, "Processor\t: %s %s (id %lu, rev %lu, cfg %lu)\n", -+ proc_info.manufacturer, proc_info.cpu_name, -+ cpu_id, cpu_rev, cpu_cfgid); -+#if defined(CONFIG_AG101_CPU_FREQ_SCALING_MODE) || defined(CONFIG_AG101_CPU_FREQ_FCS) -+ seq_printf(m, "MHz\t\t: %u\n", ag101_cpufreq_get(1) / 1000); -+#endif -+ -+ seq_printf(m, "L1I\t\t: %luKB/%luS/%luW/%luB\n", -+ CACHE_SET(ICACHE) * CACHE_WAY(ICACHE) * -+ CACHE_LINE_SIZE(ICACHE) / 1024, CACHE_SET(ICACHE), -+ CACHE_WAY(ICACHE), CACHE_LINE_SIZE(ICACHE)); -+ -+ seq_printf(m, "L1D\t\t: %luKB/%luS/%luW/%luB\n", -+ CACHE_SET(DCACHE) * CACHE_WAY(DCACHE) * -+ CACHE_LINE_SIZE(DCACHE) / 1024, CACHE_SET(DCACHE), -+ CACHE_WAY(DCACHE), CACHE_LINE_SIZE(DCACHE)); -+ -+#if defined(CONFIG_SMP) -+ for_each_online_cpu(i) { -+ seq_printf(m, "Processor\t: %d\n", i); -+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n\n", -+ per_cpu(cpu_data, -+ i).loops_per_jiffy / (500000UL / HZ), -+ (per_cpu(cpu_data, i).loops_per_jiffy / -+ (5000UL / HZ)) % 100); -+ } -+#else /* CONFIG_SMP */ -+ seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", -+ loops_per_jiffy / (500000 / HZ), -+ (loops_per_jiffy / (5000 / HZ)) % 100); -+#endif -+ -+ /* dump out the processor features */ -+ seq_puts(m, "Features\t: "); -+ -+ for (i = 0; hwcap_str[i]; i++) -+ if (elf_hwcap & (1 << i)) -+ seq_printf(m, "%s ", hwcap_str[i]); -+ -+ seq_puts(m, "\n\n"); -+ seq_printf(m, "Hardware\t: %s\n", elf_platform); -+ -+ return 0; -+} -+ -+static void *c_start(struct seq_file *m, loff_t * pos) -+{ -+ return *pos < 1 ? (void *)1 : NULL; -+} -+ -+static void *c_next(struct seq_file *m, void *v, loff_t * pos) -+{ -+ ++*pos; -+ return NULL; -+} -+ -+static void c_stop(struct seq_file *m, void *v) -+{ -+} -+ -+struct seq_operations cpuinfo_op = { -+ .start = c_start, -+ .next = c_next, -+ .stop = c_stop, -+ .show = c_show -+}; -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/signal.c linux-3.4.113/arch/nds32/kernel/signal.c ---- linux-3.4.113.orig/arch/nds32/kernel/signal.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/signal.c 2016-12-01 20:59:27.776744798 +0100 -@@ -0,0 +1,850 @@ -+/* -+ * linux/arch/nds32/kernel/signal.c -+ * -+ * Copyright (C) 1995-2002 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "ptrace.h" -+#include "signal.h" -+#include "fpu.h" -+#include "audio.h" -+ -+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) -+ -+/* -+ * For NDS32 syscalls, we encode the syscall number into the instruction. -+ */ -+#if defined( __NDS32_EL__) -+#define SWI_SYS_SIGRETURN (0xeb0e0a64) -+#define SWI_SYS_RT_SIGRETURN (0xab150a64) -+#define SWI_SYS_RESTART (0x0b000a64) /* syscall __NR_restart_syscall */ -+#define SWI_SYS_RESTART_LWIBI (0x0180af0d) /* lwi.bi $p0, [$sp], 4 */ -+#define SWI_SYS_RESTART_JRP0 (0x0068004a) /* jr $p0 */ -+#elif defined(__NDS32_EB__) -+#define SWI_SYS_SIGRETURN (0x6400000b|(__NR_sigreturn<<5)) -+#define SWI_SYS_RT_SIGRETURN (0x6400000b|(__NR_rt_sigreturn<<5)) -+#define SWI_SYS_RESTART (0x640a000b) /* syscall __NR_restart_syscall */ -+#define SWI_SYS_RESTART_LWIBI (0x0daf8001) /* lwi.bi $p0, [$sp], 4 */ -+#define SWI_SYS_RESTART_JRP0 (0x4a006800) /* jr $p0 */ -+#else -+#error "NDS32, but neither __NDS32_EB__, nor __NDS32_EL__???" -+#endif -+ -+#ifdef CONFIG_FPU -+static struct fpu_struct init_fpuregs = { -+ .fs_regs = {[0 ... 31] = sNAN32}, -+ .fd_regs = {[0 ... 15] = sNAN64}, -+ .fpcsr = FPCSR_INIT -+}; -+#endif -+#ifdef CONFIG_AUDIO -+static struct audio_struct init_audioregs = { -+ .auregs = {[0...31] = NAN32} -+}; -+#endif -+const unsigned long retcodes[2] = { -+ SWI_SYS_SIGRETURN, -+ SWI_SYS_RT_SIGRETURN -+}; -+ -+const unsigned long syscall_restart_code[3] = { -+ SWI_SYS_RESTART, /* syscall __NR_restart_syscall */ -+ SWI_SYS_RESTART_LWIBI, /* lwi.bi $p0, [$sp], 4 */ -+ SWI_SYS_RESTART_JRP0 /* jr $p0 */ -+}; -+ -+static int do_signal(sigset_t * oldset, struct pt_regs *regs, int syscall); -+ -+/* -+ * atomically swap in the new signal mask, and wait for a signal. -+ */ -+asmlinkage int sys_sigsuspend(int restart, unsigned long oldmask, -+ old_sigset_t mask, struct pt_regs *regs) -+{ -+ sigset_t blocked; -+ -+ mask &= _BLOCKABLE; -+ current->saved_sigmask = current->blocked; -+ siginitset(&blocked, mask); -+ set_current_blocked(&blocked); -+ -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ set_thread_flag(TIF_RESTORE_SIGMASK); -+ return -ERESTARTNOHAND; -+} -+ -+asmlinkage int sys_rt_sigsuspend(sigset_t __user * unewset, size_t sigsetsize, -+ struct pt_regs *regs) -+{ -+ sigset_t newset; -+ -+ /* XXX: Don't preclude handling different sized sigset_t's. */ -+ if (sigsetsize != sizeof(sigset_t)) -+ return -EINVAL; -+ -+ if (copy_from_user(&newset, unewset, sizeof(newset))) -+ return -EFAULT; -+ sigdelsetmask(&newset, ~_BLOCKABLE); -+ current->saved_sigmask = current->blocked; -+ set_current_blocked(&newset); -+ current->state = TASK_INTERRUPTIBLE; -+ schedule(); -+ set_thread_flag(TIF_RESTORE_SIGMASK); -+ return -ERESTARTNOHAND; -+} -+ -+asmlinkage int sys_sigaction(int sig, const struct old_sigaction __user * act, -+ struct old_sigaction __user * oact) -+{ -+ struct k_sigaction new_ka, old_ka; -+ int ret; -+ -+ if (act) { -+ old_sigset_t mask; -+ if (!access_ok(VERIFY_READ, act, sizeof(*act)) || -+ __get_user(new_ka.sa.sa_handler, &act->sa_handler) || -+ __get_user(new_ka.sa.sa_restorer, &act->sa_restorer)) { -+ -+ return -EFAULT; -+ } -+ __get_user(new_ka.sa.sa_flags, &act->sa_flags); -+ __get_user(mask, &act->sa_mask); -+ -+ siginitset(&new_ka.sa.sa_mask, mask); -+ } -+ -+ ret = do_sigaction(sig, act ? &new_ka : NULL, oact ? &old_ka : NULL); -+ -+ if (!ret && oact) { -+ -+ if (!access_ok(VERIFY_WRITE, oact, sizeof(*oact)) || -+ __put_user(old_ka.sa.sa_handler, &oact->sa_handler) || -+ __put_user(old_ka.sa.sa_restorer, &oact->sa_restorer)) { -+ -+ return -EFAULT; -+ } -+ __put_user(old_ka.sa.sa_flags, &oact->sa_flags); -+ __put_user(old_ka.sa.sa_mask.sig[0], &oact->sa_mask); -+ } -+ -+ return ret; -+} -+ -+/* -+ * Auxiliary signal frame. This saves stuff like FP state. -+ * The layout of this structure is not part of the user ABI. -+ */ -+struct aux_sigframe { -+}; -+ -+/* -+ * Do a signal return; undo the signal stack. These are aligned to 64-bit. -+ */ -+struct sigframe { -+ struct sigcontext sc; -+ unsigned long extramask[_NSIG_WORDS - 1]; -+ unsigned long retcode; -+ struct aux_sigframe aux __attribute__ ((aligned(8))); -+}; -+ -+struct rt_sigframe { -+ struct siginfo __user *pinfo; -+ void __user *puc; -+ struct siginfo info; -+ struct ucontext uc; -+ unsigned long retcode; -+ struct aux_sigframe aux __attribute__ ((aligned(8))); -+}; -+ -+#ifdef CONFIG_FPU -+static inline int restore_sigcontext_fpu(struct pt_regs *regs, -+ struct sigcontext __user * sc) -+{ -+ struct task_struct *tsk = current; -+ unsigned long used_math_flag; -+ int ret = 0; -+ -+ if (!(GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) -+ return 0; -+ -+ __get_user_error(used_math_flag, &sc->used_math_flag, ret); -+ -+ if (!used_math_flag) -+ return 0; -+ -+ set_used_math(); -+ -+#ifdef CONFIG_UNLAZY_FPU -+ clear_fpu(regs); -+#else -+ preempt_disable(); -+ if (current == last_task_used_math) { -+ last_task_used_math = NULL; -+ release_fpu(regs); -+ } -+ preempt_enable(); -+#endif -+ -+ return __copy_from_user(&tsk->thread.fpu, &sc->fpu, -+ sizeof(struct fpu_struct)); -+} -+ -+static inline int setup_sigcontext_fpu(struct pt_regs *regs, -+ struct sigcontext __user * sc) -+{ -+ struct task_struct *tsk = current; -+ int ret = 0; -+ -+ if (!(GET_FUCOP_EXIST() & FUCOP_EXIST_mskCP0ISFPU)) -+ return 0; -+ -+ __put_user_error(used_math(), &sc->used_math_flag, ret); -+ -+ if (!used_math()) -+ return ret; -+ -+ preempt_disable(); -+#ifdef CONFIG_UNLAZY_FPU -+ unlazy_fpu(tsk); -+#else -+ if (last_task_used_math != NULL) -+ save_fpu(last_task_used_math); -+#endif -+ ret = __copy_to_user(&sc->fpu, &tsk->thread.fpu, -+ sizeof(struct fpu_struct)); -+ -+ grab_fpu(task_pt_regs(tsk)); -+ fpload(&init_fpuregs); -+#ifndef CONFIG_UNLAZY_FPU //Lazy FPU -+ last_task_used_math = current; -+#endif -+ preempt_enable(); -+ return ret; -+} -+#else -+static inline int -+restore_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user * sc) -+{ -+ return 0; -+} -+ -+static inline int -+setup_sigcontext_fpu(struct pt_regs *regs, struct sigcontext __user * sc) -+{ -+ return 0; -+} -+#endif /* CONFIG_FPU */ -+ -+#ifdef CONFIG_AUDIO -+static inline int restore_sigcontext_audio(struct pt_regs *regs, -+ struct sigcontext __user * sc) -+{ -+ struct task_struct *tsk = current; -+ unsigned long used_audio_flag; -+ int ret = 0; -+ -+ if (!(GET_MSC_CFG() & MSC_CFG_mskAUDIO)) -+ return 0; -+ -+ __get_user_error(used_audio_flag, &sc->used_audio_flag, ret); -+ -+ if (!used_audio_flag) -+ return 0; -+ -+ set_tsk_thread_flag(tsk, TIF_USEDAUDIO); -+#ifdef CONFIG_UNLAZY_AUDIO -+ clear_audio(regs); -+#else -+ preempt_disable(); -+ if (current == last_task_used_audio) { -+ last_task_used_audio = NULL; -+ clear_audio(regs); -+ } -+ preempt_enable(); -+#endif -+ -+ return __copy_from_user(&tsk->thread.audio, &sc->audio, -+ sizeof(struct audio_struct)); -+} -+ -+static inline int setup_sigcontext_audio(struct pt_regs *regs, -+ struct sigcontext __user * sc) -+{ -+ struct task_struct *tsk = current; -+ int ret = 0; -+ -+ if (!(GET_MSC_CFG() & MSC_CFG_mskAUDIO)) -+ return 0; -+ -+ __put_user_error(test_tsk_thread_flag(tsk, TIF_USEDAUDIO), -+ &sc->used_audio_flag, ret); -+ -+ if (!test_tsk_thread_flag(tsk, TIF_USEDAUDIO)) -+ return ret; -+ -+ preempt_disable(); -+#ifdef CONFIG_UNLAZY_AUDIO -+ unlazy_audio(tsk); -+#else -+ if (NULL != last_task_used_audio) { -+ save_audio(tsk); -+ } -+#endif -+ ret = __copy_to_user(&sc->audio, &tsk->thread.audio, -+ sizeof(struct audio_struct)); -+ -+ grab_audio(task_pt_regs(tsk)); -+ audioload(&init_audioregs); -+#ifndef CONFIG_UNLAZY_AUDIO //Lazy audio -+ last_task_used_audio = current; -+#endif -+ preempt_enable(); -+ return ret; -+} -+#else /*CONFIG_AUDIO */ -+static inline int -+restore_sigcontext_audio(struct pt_regs *regs, struct sigcontext __user * sc) -+{ -+ return 0; -+} -+ -+static inline int -+setup_sigcontext_audio(struct pt_regs *regs, struct sigcontext __user * sc) -+{ -+ return 0; -+} -+#endif -+ -+static int restore_sigcontext(struct pt_regs *regs, -+ struct sigcontext __user * sc, -+ struct aux_sigframe __user * aux) -+{ -+ int err = 0; -+ -+ __get_user_error(regs->NDS32_r0, &sc->nds32_r0, err); -+ __get_user_error(regs->NDS32_r1, &sc->nds32_r1, err); -+ __get_user_error(regs->NDS32_r2, &sc->nds32_r2, err); -+ __get_user_error(regs->NDS32_r3, &sc->nds32_r3, err); -+ __get_user_error(regs->NDS32_r4, &sc->nds32_r4, err); -+ __get_user_error(regs->NDS32_r5, &sc->nds32_r5, err); -+ __get_user_error(regs->NDS32_r6, &sc->nds32_r6, err); -+ __get_user_error(regs->NDS32_r7, &sc->nds32_r7, err); -+ __get_user_error(regs->NDS32_r8, &sc->nds32_r8, err); -+ __get_user_error(regs->NDS32_r9, &sc->nds32_r9, err); -+ __get_user_error(regs->NDS32_r10, &sc->nds32_r10, err); -+ __get_user_error(regs->NDS32_r11, &sc->nds32_r11, err); -+ __get_user_error(regs->NDS32_r12, &sc->nds32_r12, err); -+ __get_user_error(regs->NDS32_r13, &sc->nds32_r13, err); -+ __get_user_error(regs->NDS32_r14, &sc->nds32_r14, err); -+ __get_user_error(regs->NDS32_r15, &sc->nds32_r15, err); -+ __get_user_error(regs->NDS32_r16, &sc->nds32_r16, err); -+ __get_user_error(regs->NDS32_r17, &sc->nds32_r17, err); -+ __get_user_error(regs->NDS32_r18, &sc->nds32_r18, err); -+ __get_user_error(regs->NDS32_r19, &sc->nds32_r19, err); -+ __get_user_error(regs->NDS32_r20, &sc->nds32_r20, err); -+ -+ __get_user_error(regs->NDS32_r21, &sc->nds32_r21, err); -+ __get_user_error(regs->NDS32_r22, &sc->nds32_r22, err); -+ __get_user_error(regs->NDS32_r23, &sc->nds32_r23, err); -+ __get_user_error(regs->NDS32_r24, &sc->nds32_r24, err); -+ __get_user_error(regs->NDS32_r25, &sc->nds32_r25, err); -+ __get_user_error(regs->NDS32_fp, &sc->nds32_fp, err); -+ __get_user_error(regs->NDS32_gp, &sc->nds32_gp, err); -+ __get_user_error(regs->NDS32_lp, &sc->nds32_lp, err); -+ __get_user_error(regs->NDS32_sp, &sc->nds32_sp, err); -+ -+ __get_user_error(regs->NDS32_ipc, &sc->nds32_ipc, err); -+#if defined(CONFIG_HWZOL) -+ __get_user_error(regs->NDS32_lc, &sc->zol.nds32_lc, err); -+ __get_user_error(regs->NDS32_le, &sc->zol.nds32_le, err); -+ __get_user_error(regs->NDS32_lb, &sc->zol.nds32_lb, err); -+#endif -+ -+ err |= !valid_user_regs(regs); -+ err |= restore_sigcontext_audio(regs, sc); -+ err |= restore_sigcontext_fpu(regs, sc); -+ -+ return err; -+} -+ -+asmlinkage int sys_sigreturn(struct pt_regs *regs) -+{ -+ struct sigframe __user *frame; -+ sigset_t set; -+ -+ /* Always make any pending restarted system calls return -EINTR */ -+ current_thread_info()->restart_block.fn = do_no_restart_syscall; -+ -+ /* -+ * Since we stacked the signal on a 64-bit boundary, -+ * then 'sp' should be word aligned here. If it's -+ * not, then the user is trying to mess with us. -+ */ -+ if (regs->NDS32_sp & 7) -+ goto badframe; -+ -+ frame = (struct sigframe __user *)regs->NDS32_sp; -+ -+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) -+ goto badframe; -+ -+ if (__get_user(set.sig[0], &frame->sc.oldmask) -+ || (_NSIG_WORDS > 1 -+ && __copy_from_user(&set.sig[1], &frame->extramask, -+ sizeof(frame->extramask)))) -+ goto badframe; -+ -+ sigdelsetmask(&set, ~_BLOCKABLE); -+ spin_lock_irq(¤t->sighand->siglock); -+ current->blocked = set; -+ recalc_sigpending(); -+ spin_unlock_irq(¤t->sighand->siglock); -+ -+ if (restore_sigcontext(regs, &frame->sc, &frame->aux)) -+ goto badframe; -+ -+ return regs->NDS32_r0; -+ -+badframe: -+ force_sig(SIGSEGV, current); -+ return 0; -+} -+ -+asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) -+{ -+ struct rt_sigframe __user *frame; -+ sigset_t set; -+ -+ /* Always make any pending restarted system calls return -EINTR */ -+ current_thread_info()->restart_block.fn = do_no_restart_syscall; -+ -+ /* -+ * Since we stacked the signal on a 64-bit boundary, -+ * then 'sp' should be word aligned here. If it's -+ * not, then the user is trying to mess with us. -+ */ -+ if (regs->NDS32_sp & 7) -+ goto badframe; -+ -+ frame = (struct rt_sigframe __user *)regs->NDS32_sp; -+ -+ if (!access_ok(VERIFY_READ, frame, sizeof(*frame))) -+ goto badframe; -+ -+ if (__copy_from_user(&set, &frame->uc.uc_sigmask, sizeof(set))) -+ goto badframe; -+ -+ sigdelsetmask(&set, ~_BLOCKABLE); -+ spin_lock_irq(¤t->sighand->siglock); -+ current->blocked = set; -+ recalc_sigpending(); -+ spin_unlock_irq(¤t->sighand->siglock); -+ -+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext, &frame->aux)) -+ goto badframe; -+ -+ if (do_sigaltstack(&frame->uc.uc_stack, NULL, regs->NDS32_sp) == -+ -EFAULT) -+ goto badframe; -+ -+ return regs->NDS32_r0; -+ -+badframe: -+ force_sig(SIGSEGV, current); -+ return 0; -+} -+ -+static int setup_sigcontext(struct sigcontext __user * sc, -+ struct aux_sigframe __user * aux, -+ struct pt_regs *regs, unsigned long mask) -+{ -+ int err = 0; -+ -+ err |= setup_sigcontext_fpu(regs, sc); -+ err |= setup_sigcontext_audio(regs, sc); -+ -+ __put_user_error(regs->NDS32_r0, &sc->nds32_r0, err); -+ __put_user_error(regs->NDS32_r1, &sc->nds32_r1, err); -+ __put_user_error(regs->NDS32_r2, &sc->nds32_r2, err); -+ __put_user_error(regs->NDS32_r3, &sc->nds32_r3, err); -+ __put_user_error(regs->NDS32_r4, &sc->nds32_r4, err); -+ __put_user_error(regs->NDS32_r5, &sc->nds32_r5, err); -+ __put_user_error(regs->NDS32_r6, &sc->nds32_r6, err); -+ __put_user_error(regs->NDS32_r7, &sc->nds32_r7, err); -+ __put_user_error(regs->NDS32_r8, &sc->nds32_r8, err); -+ __put_user_error(regs->NDS32_r9, &sc->nds32_r9, err); -+ __put_user_error(regs->NDS32_r10, &sc->nds32_r10, err); -+ __put_user_error(regs->NDS32_r11, &sc->nds32_r11, err); -+ __put_user_error(regs->NDS32_r12, &sc->nds32_r12, err); -+ __put_user_error(regs->NDS32_r13, &sc->nds32_r13, err); -+ __put_user_error(regs->NDS32_r14, &sc->nds32_r14, err); -+ __put_user_error(regs->NDS32_r15, &sc->nds32_r15, err); -+ __put_user_error(regs->NDS32_r16, &sc->nds32_r16, err); -+ __put_user_error(regs->NDS32_r17, &sc->nds32_r17, err); -+ __put_user_error(regs->NDS32_r18, &sc->nds32_r18, err); -+ __put_user_error(regs->NDS32_r19, &sc->nds32_r19, err); -+ __put_user_error(regs->NDS32_r20, &sc->nds32_r20, err); -+ -+ __put_user_error(regs->NDS32_r21, &sc->nds32_r21, err); -+ __put_user_error(regs->NDS32_r22, &sc->nds32_r22, err); -+ __put_user_error(regs->NDS32_r23, &sc->nds32_r23, err); -+ __put_user_error(regs->NDS32_r24, &sc->nds32_r24, err); -+ __put_user_error(regs->NDS32_r25, &sc->nds32_r25, err); -+ __put_user_error(regs->NDS32_fp, &sc->nds32_fp, err); -+ __put_user_error(regs->NDS32_gp, &sc->nds32_gp, err); -+ __put_user_error(regs->NDS32_lp, &sc->nds32_lp, err); -+ __put_user_error(regs->NDS32_sp, &sc->nds32_sp, err); -+ __put_user_error(regs->NDS32_ipc, &sc->nds32_ipc, err); -+#if defined(CONFIG_HWZOL) -+ __get_user_error(regs->NDS32_lc, &sc->zol.nds32_lc, err); -+ __get_user_error(regs->NDS32_le, &sc->zol.nds32_le, err); -+ __get_user_error(regs->NDS32_lb, &sc->zol.nds32_lb, err); -+#endif -+ -+ __put_user_error(current->thread.trap_no, &sc->trap_no, err); -+ __put_user_error(current->thread.error_code, &sc->error_code, err); -+ __put_user_error(current->thread.address, &sc->fault_address, err); -+ __put_user_error(mask, &sc->oldmask, err); -+ -+ return err; -+} -+ -+static inline void __user *get_sigframe(struct k_sigaction *ka, -+ struct pt_regs *regs, int framesize) -+{ -+ unsigned long sp = regs->NDS32_sp; -+ void __user *frame; -+ -+ /* -+ * This is the X/Open sanctioned signal stack switching. -+ */ -+ if ((ka->sa.sa_flags & SA_ONSTACK) && !sas_ss_flags(sp)) -+ sp = current->sas_ss_sp + current->sas_ss_size; -+ -+ /* -+ * ATPCS B01 mandates 8-byte alignment -+ */ -+ frame = (void __user *)((sp - framesize) & ~7); -+ -+ /* -+ * Check that we can actually write to the signal frame. -+ */ -+ if (!access_ok(VERIFY_WRITE, frame, framesize)) -+ frame = NULL; -+ -+ return frame; -+} -+ -+static int setup_return(struct pt_regs *regs, struct k_sigaction *ka, -+ unsigned long __user * rc, void __user * frame, -+ int usig) -+{ -+ unsigned long handler = (unsigned long)ka->sa.sa_handler; -+ unsigned long retcode; -+ struct sigframe *sf = (struct sigframe *)frame; -+ -+ /* -+ * Maybe we need to deliver a 32-bit signal to a 26-bit task. -+ */ -+ if (ka->sa.sa_flags & SA_RESTORER) { -+ retcode = (unsigned long)ka->sa.sa_restorer; -+ } else { -+ -+ unsigned int idx = 0; //thumb; -+ unsigned long line_size = CACHE_LINE_SIZE(ICACHE); -+ unsigned long start, end; -+ -+ if (ka->sa.sa_flags & SA_SIGINFO) -+ idx++; -+ -+ if (__put_user(retcodes[idx], rc)) -+ return 1; -+ -+ /* -+ * Ensure that the instruction cache sees -+ * the return code written onto the stack. -+ */ -+ start = (unsigned long)rc & ~(line_size - 1); -+ end = start + line_size; -+ flush_icache_range(start, end); -+ -+ retcode = KERN_SIGRETURN_CODE + (idx << 2); -+ } -+ -+ regs->NDS32_r0 = usig; -+ regs->NDS32_r1 = 0; -+ regs->NDS32_r2 = (unsigned long)&sf->sc; -+ regs->NDS32_sp = (unsigned long)frame; -+ regs->NDS32_lp = retcode; -+ regs->NDS32_ipc = handler; -+ /* Also store handler address in r15 for updating GP in the handler. */ -+ regs->NDS32_r15 = handler; -+ -+ return 0; -+} -+ -+static int setup_frame(int usig, struct k_sigaction *ka, sigset_t * set, -+ struct pt_regs *regs) -+{ -+ struct sigframe __user *frame = get_sigframe(ka, regs, sizeof(*frame)); -+ int err = 0; -+ -+ if (!frame) -+ return 1; -+ -+ err |= setup_sigcontext(&frame->sc, &frame->aux, regs, set->sig[0]); -+ -+ if (_NSIG_WORDS > 1) { -+ err |= __copy_to_user(frame->extramask, &set->sig[1], -+ sizeof(frame->extramask)); -+ } -+ -+ if (err == 0) -+ err = setup_return(regs, ka, &frame->retcode, frame, usig); -+ -+ return err; -+} -+ -+static int setup_rt_frame(int usig, struct k_sigaction *ka, siginfo_t * info, -+ sigset_t * set, struct pt_regs *regs) -+{ -+ struct rt_sigframe __user *frame = -+ get_sigframe(ka, regs, sizeof(*frame)); -+ stack_t stack; -+ int err = 0; -+ -+ if (!frame) -+ return 1; -+ -+ __put_user_error(&frame->info, &frame->pinfo, err); -+ __put_user_error(&frame->uc, &frame->puc, err); -+ err |= copy_siginfo_to_user(&frame->info, info); -+ -+ __put_user_error(0, &frame->uc.uc_flags, err); -+ __put_user_error(NULL, &frame->uc.uc_link, err); -+ -+ memset(&stack, 0, sizeof(stack)); -+ stack.ss_sp = (void __user *)current->sas_ss_sp; -+ stack.ss_flags = sas_ss_flags(regs->NDS32_sp); //NDS32_sp -+ stack.ss_size = current->sas_ss_size; -+ err |= __copy_to_user(&frame->uc.uc_stack, &stack, sizeof(stack)); -+ -+ err |= setup_sigcontext(&frame->uc.uc_mcontext, &frame->aux, -+ regs, set->sig[0]); -+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); -+ -+ if (err == 0) -+ err = setup_return(regs, ka, &frame->retcode, frame, usig); -+ -+ if (err == 0) { -+ /* -+ * For realtime signals we must also set the second and third -+ * arguments for the signal handler. -+ * -- Peter Maydell 2000-12-06 -+ */ -+ regs->NDS32_r1 = (unsigned long)&frame->info; -+ regs->NDS32_r2 = (unsigned long)&frame->uc; -+ } -+ -+ return err; -+} -+ -+static inline void setup_restart_syscall(struct pt_regs *regs) -+{ -+ regs->NDS32_r0 = regs->NDS32_ORIG_r0; -+ regs->NDS32_ipc -= 4; -+} -+ -+/* -+ * OK, we're invoking a handler -+ */ -+static void handle_signal(unsigned long sig, struct k_sigaction *ka, -+ siginfo_t * info, sigset_t * oldset, -+ struct pt_regs *regs, int syscall) -+{ -+ struct thread_info *thread = current_thread_info(); -+ struct task_struct *tsk = current; -+ int usig = sig; -+ int ret; -+ -+ /* -+ * If we were from a system call, check for system call restarting... -+ */ -+ if (syscall) { -+ switch (regs->NDS32_r0) { -+ case -ERESTART_RESTARTBLOCK: -+ case -ERESTARTNOHAND: -+ regs->NDS32_r0 = -EINTR; -+ break; -+ case -ERESTARTSYS: -+ if (!(ka->sa.sa_flags & SA_RESTART)) { -+ regs->NDS32_r0 = -EINTR; -+ break; -+ } -+ /* fallthrough */ -+ case -ERESTARTNOINTR: -+ setup_restart_syscall(regs); -+ } -+ } -+ -+ /* -+ * translate the signal -+ */ -+ if (usig < 32 && thread->exec_domain -+ && thread->exec_domain->signal_invmap) -+ usig = thread->exec_domain->signal_invmap[usig]; -+ -+ /* -+ * Set up the stack frame -+ */ -+ if (ka->sa.sa_flags & SA_SIGINFO) -+ ret = setup_rt_frame(usig, ka, info, oldset, regs); -+ else -+ ret = setup_frame(usig, ka, oldset, regs); -+ -+ /* -+ * Check that the resulting registers are actually sane. -+ */ -+ ret |= !valid_user_regs(regs); -+ -+ /* -+ * Block the signal if we were unsuccessful. -+ */ -+ if (ret == 0) { -+ spin_lock_irq(&tsk->sighand->siglock); -+ sigorsets(&tsk->blocked, &tsk->blocked, &ka->sa.sa_mask); -+ if (!(ka->sa.sa_flags & SA_NODEFER)) -+ sigaddset(&tsk->blocked, sig); -+ recalc_sigpending(); -+ spin_unlock_irq(&tsk->sighand->siglock); -+#if 0 & defined(CONFIG_HSS) -+ /* COLE: i marked this tempory. -+ It doesn't behave the same as x86 */ -+ /* Clear HSS when entering the signal handler, -+ User should be step into signal handler */ -+ if (regs->NDS32_ipsw & PSW_mskHSS) { -+ regs->NDS32_ipsw &= ~PSW_mskHSS; -+ printk(KERN_INFO "clear for sig %d. pc=0x%08x\n", sig, -+ regs->NDS32_ipc); -+ } -+#endif -+ return; -+ } -+ -+ force_sigsegv(sig, tsk); -+} -+ -+/* -+ * Note that 'init' is a special process: it doesn't get signals it doesn't -+ * want to handle. Thus you cannot kill init even with a SIGKILL even by -+ * mistake. -+ * -+ * Note that we go through the signals twice: once to check the signals that -+ * the kernel can handle, and then we build all the user-level signal handling -+ * stack-frames in one go after that. -+ */ -+asmlinkage int do_signal(sigset_t * oldset, struct pt_regs *regs, int syscall) -+{ -+ struct k_sigaction ka; -+ siginfo_t info; -+ int signr; -+ -+ /* -+ * We want the common case to go fast, which -+ * is why we may in certain cases get here from -+ * kernel mode. Just return without doing anything -+ * if so. -+ */ -+ -+ if (!user_mode(regs)) -+ return 0; -+ -+ if (try_to_freeze()) -+ goto no_signal; -+ -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) -+ oldset = ¤t->saved_sigmask; -+ -+ signr = get_signal_to_deliver(&info, &ka, regs, NULL); -+ -+ if (signr > 0) { -+ handle_signal(signr, &ka, &info, oldset, regs, syscall); -+ /* -+ * A signal was successfully delivered; the saved -+ * sigmask will have been stored in the signal frame, -+ * and will be restored by sigreturn, so we can simply -+ * clear the TIF_RESTORE_SIGMASK flag. -+ */ -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) -+ clear_thread_flag(TIF_RESTORE_SIGMASK); -+ return 1; -+ } -+ -+no_signal: -+ /* -+ * No signal to deliver to the process - restart the syscall. -+ */ -+ if (syscall) { -+ switch (regs->NDS32_r0) { -+ u32 __user *usp; -+ -+ case -ERESTART_RESTARTBLOCK: -+ regs->NDS32_sp -= 4; -+ usp = (u32 __user *) regs->NDS32_sp; -+ -+ if (put_user(regs->NDS32_ipc, usp) == 0) -+ regs->NDS32_ipc = KERN_RESTART_CODE; -+ else { -+ regs->NDS32_sp += 4; -+ force_sigsegv(0, current); -+ } -+ regs->NDS32_r0 = regs->NDS32_ORIG_r0; -+ break; -+ -+ case -ERESTARTNOHAND: -+ case -ERESTARTSYS: -+ case -ERESTARTNOINTR: -+ -+ setup_restart_syscall(regs); -+ break; -+ } -+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) { -+ clear_thread_flag(TIF_RESTORE_SIGMASK); -+ sigprocmask(SIG_SETMASK, ¤t->saved_sigmask, NULL); -+ } -+ } -+ -+ return 0; -+} -+ -+asmlinkage void do_notify_resume(struct pt_regs *regs, -+ unsigned int thread_flags, int syscall) -+{ -+ if (thread_flags & _TIF_SIGPENDING) -+ do_signal(¤t->blocked, regs, syscall); -+ if (thread_flags & _TIF_NOTIFY_RESUME) { -+ clear_thread_flag(TIF_NOTIFY_RESUME); -+ tracehook_notify_resume(regs); -+ if (current->replacement_session_keyring) -+ key_replace_session_keyring(); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/signal.h linux-3.4.113/arch/nds32/kernel/signal.h ---- linux-3.4.113.orig/arch/nds32/kernel/signal.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/signal.h 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,20 @@ -+/* -+ * linux/arch/arm/kernel/signal.h -+ * -+ * Copyright (C) 2005-2009 Russell King. -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+ -+#include -+ -+#define RETURN_SYSCALL_BASE (0x2000) -+#define RETURN_SYSCALL_PA_BASE (PHYS_OFFSET | RETURN_SYSCALL_BASE) -+ -+#define KERN_SIGRETURN_CODE (fix_to_virt(FIX_RETURN_SYSCALL)) -+#define KERN_RESTART_CODE (KERN_SIGRETURN_CODE + sizeof(retcodes)) -+ -+extern const unsigned long retcodes[2]; -+extern const unsigned long syscall_restart_code[3]; -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/smp.c linux-3.4.113/arch/nds32/kernel/smp.c ---- linux-3.4.113.orig/arch/nds32/kernel/smp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/smp.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,335 @@ -+/* -+ * linux/arch/nds32/kernel/smp.c -+ * -+ * Copyright (C) 2002 ARM Limited, All Rights Reserved. -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+void smp_init_cpus(void) -+{ -+ int i; -+ for (i = 0; i < NR_CPUS; i++) -+ cpu_set(i, cpu_possible_map); -+} -+ -+int setup_profiling_timer(unsigned int multiplier) -+{ -+ return 0; -+} -+ -+struct tlb_data { -+ struct vm_area_struct *vma; -+ unsigned long start; -+ unsigned long end; -+}; -+ -+static void ipi_flush_tlb_all(void *data) -+{ -+ local_flush_tlb_all(); -+} -+ -+void flush_tlb_all(void) -+{ -+ on_each_cpu(ipi_flush_tlb_all, NULL, 1); -+} -+ -+static void ipi_flush_tlb_mm(void *data) -+{ -+ struct mm_struct *mm = (struct mm_struct *)data; -+ local_flush_tlb_mm(mm); -+} -+ -+void flush_tlb_mm(struct mm_struct *mm) -+{ -+ on_each_cpu(ipi_flush_tlb_mm, mm, 1); -+} -+ -+static void ipi_flush_tlb_page(void *data) -+{ -+ struct tlb_data *t = (struct tlb_data *)data; -+ local_flush_tlb_page(t->vma, t->start); -+} -+ -+void flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -+{ -+ struct tlb_data data; -+ -+ data.vma = vma; -+ data.start = addr; -+ on_each_cpu(ipi_flush_tlb_page, &data, 1); -+} -+ -+static void ipi_flush_tlb_range(void *data) -+{ -+ struct tlb_data *t = (struct tlb_data *)data; -+ local_flush_tlb_range(t->vma, t->start, t->end); -+} -+ -+void flush_tlb_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+ struct tlb_data data; -+ -+ data.vma = vma; -+ data.start = start; -+ data.end = end; -+ on_each_cpu(ipi_flush_tlb_range, &data, 1); -+} -+ -+static void ipi_flush_tlb_kernel_range(void *data) -+{ -+ struct tlb_data *t = (struct tlb_data *)data; -+ local_flush_tlb_kernel_range(t->start, t->end); -+} -+ -+void flush_tlb_kernel_range(unsigned long start, unsigned long end) -+{ -+ struct tlb_data data; -+ -+ data.start = start; -+ data.end = end; -+ on_each_cpu(ipi_flush_tlb_kernel_range, &data, 1); -+} -+ -+/* IPI implementation */ -+static inline unsigned long read_ipi_trigger(void) -+{ -+ /* AMIC IPI trigger register */ -+ return *(volatile unsigned long *)(AMIC_VA_BASE + 0x40); -+} -+ -+static inline void write_ipi_trigger(const struct cpumask *mask) -+{ -+ unsigned long data = *cpus_addr(*mask); -+ *(volatile unsigned long *)(AMIC_VA_BASE + 0x40) = data; -+} -+ -+static inline void clear_ipi_status(void) -+{ -+ *(volatile unsigned long *)(AMIC_VA_BASE + 0x44) = 0xf; -+ asm("msync store\nisb"); -+} -+ -+static void __init send_IPI_boot(int cpu, struct task_struct *tsk) -+{ -+ extern void secondary_startup(void); -+ unsigned long *ptr = (unsigned long *)(0xc0006000 + (cpu << 9)); -+ ptr[5] = virt_to_phys(secondary_startup); -+ ptr[6] = (unsigned long)task_stack_page(tsk) + THREAD_SIZE - 8; -+ asm("cctl %0, L1D_VA_WB, alevel\n"::"r"(ptr)); -+ asm("cctl %0, L1D_VA_INVAL, alevel\nmsync\ndsb\n"::"r"(ptr)); -+ write_ipi_trigger(get_cpu_mask(cpu)); -+} -+ -+static int __init wait_cpu_boot_done(int cpu) -+{ -+ int i, state; -+ for (i = 0; i < 10000; i++) { -+ state = read_ipi_trigger(); -+ if ((state & (1 << cpu)) == 0) -+ break; -+ udelay(100); -+ } -+ return (i == 10000) ? -1 : 0; -+} -+ -+void __init secondary_start_kernel(void) -+{ -+ unsigned long tmp; -+ unsigned int cpu = smp_processor_id(); -+ -+ atomic_inc(&init_mm.mm_count); -+ current->active_mm = &init_mm; -+ -+ /* -+ * enable cache. -+ */ -+ -+#ifdef CONFIG_ANDES_PAGE_SIZE_4KB -+ if (CPU_IS_N1213_43U1HA0()) { -+ /* Downsize cache to bypass cache aliasing issue */ -+ -+ if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096) -+ tmp = 0x02 << SDZ_CTL_offICDZ; -+ -+ if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096) -+ tmp |= 0x02 << SDZ_CTL_offDCDZ; -+ -+ SET_SDZ_CTL(tmp); -+ ISB(); -+// printk("CPU%d enabled cache downsizing.\n", cpu); -+ } -+#endif /* CONFIG_ANDES_PAGE_SIZE_4KB */ -+ -+ tmp = GET_CACHE_CTL(); -+#ifndef CONFIG_CPU_DCACHE_DISABLE -+ tmp |= CACHE_CTL_mskDC_EN; -+#endif -+ -+#ifndef CONFIG_CPU_ICACHE_DISABLE -+ tmp |= CACHE_CTL_mskIC_EN; -+#endif -+ SET_CACHE_CTL(tmp); -+ DSB(); -+ ISB(); -+ -+ preempt_disable(); -+ local_irq_enable(); -+ -+ //assume all of cores runs the same speed -+ //calibrate_delay(); -+ /* store cpu info ot the second cpu */ -+ smp_store_cpu_info(cpu); -+ -+ clear_ipi_status(); -+ cpu_idle(); -+} -+ -+/* -+ * Called by both boot and secondaries to move global data into -+ * per-processor storage. -+ */ -+void __init smp_store_cpu_info(unsigned int cpuid) -+{ -+ struct cpuinfo_nds32 *cpu_info = &per_cpu(cpu_data, cpuid); -+ -+ cpu_info->loops_per_jiffy = loops_per_jiffy; -+} -+ -+/* functions be used by generic layer */ -+void arch_send_call_function_single_ipi(int cpu) -+{ -+ write_ipi_trigger(get_cpu_mask(cpu)); -+} -+ -+void arch_send_call_function_ipi_mask(const struct cpumask *mask) -+{ -+ write_ipi_trigger(mask); -+} -+ -+static void __init smp_boot_one_cpu(int cpu) -+{ -+ struct task_struct *idle; -+ int ret; -+ -+ idle = fork_idle(cpu); -+ if (IS_ERR(idle)) -+ panic(KERN_ERR "Fork failed for CPU %d", cpu); -+ -+ send_IPI_boot(cpu, idle); -+ ret = wait_cpu_boot_done(cpu); -+ if (ret == 0) -+ cpu_set(cpu, cpu_online_map); -+ else -+ put_task_struct(idle); -+} -+ -+static void ipi_timer(void *data) -+{ -+ profile_tick(CPU_PROFILING); -+ update_process_times(user_mode(get_irq_regs())); -+} -+ -+void smp_send_timer(void) -+{ -+ smp_call_function(ipi_timer, NULL, 0); -+} -+ -+static void ipi_stop(void *data) -+{ -+ cpu_clear(smp_processor_id(), cpu_online_map); -+ local_irq_enable(); -+ for (;;) ; -+} -+ -+void smp_send_stop(void) -+{ -+ smp_call_function(ipi_stop, NULL, 0); -+} -+ -+void smp_send_reschedule(int cpu) -+{ -+ write_ipi_trigger(get_cpu_mask(cpu)); -+} -+ -+static void ipi_handler(unsigned int irq, struct irq_desc *desc) -+{ -+ clear_ipi_status(); -+ generic_smp_call_function_single_interrupt(); -+ generic_smp_call_function_interrupt(); -+} -+ -+void __init smp_prepare_cpus(unsigned int max_cpus) -+{ -+ /* -+ * XXX detect how many cores exist -+ */ -+ int i; -+ unsigned int cpu = smp_processor_id(); -+ -+ /* store master core cpu info */ -+ smp_store_cpu_info(cpu); -+ for (i = 0; i < max_cpus; i++) -+ cpu_set(i, cpu_present_map); -+ -+ /* setup IPI handler */ -+ set_irq_chip(32, &dummy_irq_chip); -+ set_irq_chained_handler(32, ipi_handler); -+} -+ -+int __cpuinit __cpu_up(unsigned int cpu) -+{ -+ smp_boot_one_cpu(cpu); -+ return cpu_online(cpu) ? 0 : -ENOSYS; -+} -+ -+void __init smp_cpus_done(unsigned int max_cpus) -+{ -+ int cpu; -+ unsigned long bogosum = 0; -+ -+ for_each_online_cpu(cpu) -+ bogosum += per_cpu(cpu_data, cpu).loops_per_jiffy; -+ -+ printk(KERN_INFO "SMP: Total of %d processors activated " -+ "(%lu.%02lu BogoMIPS).\n", -+ num_online_cpus(), -+ bogosum / (500000 / HZ), (bogosum / (5000 / HZ)) % 100); -+ -+ /* now we can set all interruption don't cared */ -+ *(volatile unsigned long *)(AMIC_VA_BASE + 0x4) = 0xffffffff; -+} -+ -+void __init smp_prepare_boot_cpu(void) -+{ -+ unsigned int cpu = smp_processor_id(); -+ unsigned long *ptr = (unsigned long *)(0xc0006000 + (cpu << 9)); -+ ptr[4] = 1; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/stacktrace.c linux-3.4.113/arch/nds32/kernel/stacktrace.c ---- linux-3.4.113.orig/arch/nds32/kernel/stacktrace.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/stacktrace.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,41 @@ -+#include -+#include -+void save_stack_trace(struct stack_trace *trace) -+{ -+ save_stack_trace_tsk(current, trace); -+} -+ -+void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) -+{ -+ unsigned long *fpn; -+ int skip = trace->skip; -+ int savesched; -+ -+ if (tsk == current) { -+ __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn)); -+ savesched = 1; -+ } else { -+ fpn = (unsigned long *)thread_saved_fp(tsk); -+ savesched = 0; -+ } -+ -+ while (!kstack_end(fpn) && !((unsigned long)fpn & 0x3) -+ && (fpn >= (unsigned long *)TASK_SIZE)) { -+ unsigned long lpp, fpp; -+ lpp = fpn[0]; -+ fpp = fpn[-1]; -+ if (!__kernel_text_address(lpp)) -+ break; -+ -+ if (savesched || !in_sched_functions(lpp)) { -+ if (skip) { -+ skip--; -+ } else { -+ trace->entries[trace->nr_entries++] = lpp; -+ if (trace->nr_entries >= trace->max_entries) -+ break; -+ } -+ } -+ fpn = (unsigned long *)fpp; -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/sys_nds32.c linux-3.4.113/arch/nds32/kernel/sys_nds32.c ---- linux-3.4.113.orig/arch/nds32/kernel/sys_nds32.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/sys_nds32.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,331 @@ -+/* -+ * linux/arch/nds32/kernel/sys_nds32.c -+ * -+ * Copyright (C) People who wrote linux/arch/i386/kernel/sys_i386.c -+ * Copyright (C) 2007 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * This file contains various random system calls that -+ * have a non-standard calling sequence on the Linux/nds32 -+ * platform. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+extern unsigned long do_mremap(unsigned long addr, unsigned long old_len, -+ unsigned long new_len, unsigned long flags, -+ unsigned long new_addr); -+ -+struct mmap_arg_struct { -+ unsigned long addr; -+ unsigned long len; -+ unsigned long prot; -+ unsigned long flags; -+ unsigned long fd; -+ unsigned long offset; -+}; -+ -+asmlinkage unsigned long sys_mmap2(unsigned long addr, unsigned long len, -+ unsigned long prot, unsigned long flags, -+ unsigned long fd, unsigned long pgoff) -+{ -+ if (pgoff & (~PAGE_MASK >> 12)) -+ return -EINVAL; -+ -+ return sys_mmap_pgoff(addr, len, prot, flags, fd, -+ pgoff >> (PAGE_SHIFT - 12)); -+} -+ -+asmlinkage unsigned long -+sys_nds32_mremap(unsigned long addr, unsigned long old_len, -+ unsigned long new_len, unsigned long flags, -+ unsigned long new_addr) -+{ -+ unsigned long ret = -EINVAL; -+ -+ if (flags & MREMAP_FIXED && new_addr < FIRST_USER_ADDRESS) -+ goto out; -+ -+ down_write(¤t->mm->mmap_sem); -+ ret = do_mremap(addr, old_len, new_len, flags, new_addr); -+ up_write(¤t->mm->mmap_sem); -+ -+out: -+ return ret; -+} -+ -+/* -+ * Perform the select(nd, in, out, ex, tv) and mmap() system -+ * calls. -+ */ -+ -+struct sel_arg_struct { -+ unsigned long n; -+ fd_set __user *inp, *outp, *exp; -+ struct timeval __user *tvp; -+}; -+ -+asmlinkage int old_select(struct sel_arg_struct __user * arg) -+{ -+ struct sel_arg_struct a; -+ -+ if (copy_from_user(&a, arg, sizeof(a))) -+ return -EFAULT; -+ /* sys_select() does the appropriate kernel locking */ -+ return sys_select(a.n, a.inp, a.outp, a.exp, a.tvp); -+} -+ -+/* -+ * sys_ipc() is the de-multiplexer for the SysV IPC calls.. -+ * -+ * This is really horribly ugly. -+ */ -+asmlinkage long sys_ipc(unsigned int call, int first, unsigned long second, -+ unsigned long third, void __user * ptr, long fifth) -+{ -+ int version, ret; -+ -+ version = call >> 16; /* hack for backward compatibility */ -+ call &= 0xffff; -+ -+ switch (call) { -+ case SEMOP: -+ return sys_semtimedop(first, (struct sembuf __user *)ptr, -+ second, NULL); -+ case SEMTIMEDOP: -+ return sys_semtimedop(first, (struct sembuf __user *)ptr, -+ second, -+ (const struct timespec __user *)fifth); -+ -+ case SEMGET: -+ return sys_semget(first, second, third); -+ case SEMCTL:{ -+ union semun fourth; -+ if (!ptr) -+ return -EINVAL; -+ if (get_user(fourth.__pad, (void __user * __user *)ptr)) -+ return -EFAULT; -+ return sys_semctl(first, second, third, fourth); -+ } -+ -+ case MSGSND: -+ return sys_msgsnd(first, (struct msgbuf __user *)ptr, -+ second, third); -+ case MSGRCV: -+ switch (version) { -+ case 0:{ -+ struct ipc_kludge tmp; -+ if (!ptr) -+ return -EINVAL; -+ if (copy_from_user -+ (&tmp, (struct ipc_kludge __user *)ptr, -+ sizeof(tmp))) -+ return -EFAULT; -+ return sys_msgrcv(first, tmp.msgp, second, -+ tmp.msgtyp, third); -+ } -+ default: -+ return sys_msgrcv(first, -+ (struct msgbuf __user *)ptr, -+ second, fifth, third); -+ } -+ case MSGGET: -+ return sys_msgget((key_t) first, second); -+ case MSGCTL: -+ return sys_msgctl(first, second, (struct msqid_ds __user *)ptr); -+ -+ case SHMAT: -+ switch (version) { -+ default:{ -+ ulong raddr; -+ ret = -+ do_shmat(first, (char __user *)ptr, second, -+ &raddr); -+ if (ret) -+ return ret; -+ return put_user(raddr, (ulong __user *) third); -+ } -+ case 1: /* Of course, we don't support iBCS2! */ -+ return -EINVAL; -+ } -+ case SHMDT: -+ return sys_shmdt((char __user *)ptr); -+ case SHMGET: -+ return sys_shmget(first, second, third); -+ case SHMCTL: -+ return sys_shmctl(first, second, (struct shmid_ds __user *)ptr); -+ default: -+ return -ENOSYS; -+ } -+} -+ -+/* Fork a new task - this creates a new program thread. -+ * This is called indirectly via a small wrapper -+ */ -+asmlinkage int sys_fork(struct pt_regs *regs) -+{ -+ return do_fork(SIGCHLD, regs->NDS32_sp, regs, 0, NULL, NULL); -+} -+ -+/* Clone a task - this clones the calling program thread. -+ * This is called indirectly via a small wrapper -+ */ -+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long newsp, -+ int __user * parent_tidptr, int tls_val, -+ int __user * child_tidptr, struct pt_regs *regs) -+{ -+ if (!newsp) -+ newsp = regs->NDS32_sp; -+ -+ return do_fork(clone_flags, newsp, regs, 0, parent_tidptr, -+ child_tidptr); -+} -+ -+asmlinkage int sys_vfork(struct pt_regs *regs) -+{ -+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->NDS32_sp, regs, -+ 0, NULL, NULL); -+} -+ -+/* sys_execve() executes a new program. -+ * This is called indirectly via a small wrapper -+ */ -+asmlinkage int sys_execve(const char __user * filenamei, -+ const char __user * const __user * argv, -+ const char __user * const __user * envp, -+ struct pt_regs *regs) -+{ -+ int error; -+ char *filename; -+ -+ filename = getname(filenamei); -+ error = PTR_ERR(filename); -+ if (IS_ERR(filename)) -+ goto out; -+ -+ error = do_execve(filename, argv, envp, regs); -+ putname(filename); -+ -+out: -+ return error; -+} -+ -+asmlinkage unsigned long sys_getpagesize(void) -+{ -+ return PAGE_SIZE; /* Possibly older binaries want 8192 on sun4's? */ -+} -+ -+int kernel_execve(const char *filename, const char *const argv[], -+ const char *const envp[]) -+{ -+ struct pt_regs regs; -+ int ret; -+ -+ memset(®s, 0, sizeof(struct pt_regs)); -+ ret = do_execve(filename, argv, envp, ®s); -+ -+ if (ret < 0) { -+ goto out; -+ } -+ /* -+ * Save argc to the register structure for userspace. -+ */ -+ regs.NDS32_r0 = ret; -+ -+ /* -+ * We were successful. We won't be returning to our caller, but -+ * instead to user space by manipulating the kernel stack. -+ */ -+ asm("addi $r0, %0, %1\n\t" -+ "move $r1, %2\n\t" -+ "move $r2, %3\n\t" -+ "bal memmove\n\t" /* copy regs to top of stack */ -+ "move $r8, #0\n\t" /* not a syscall */ -+ "move $r9, %0\n\t" /* thread structure */ -+ "move $sp, $r0\n\t" /* reposition stack pointer */ -+"b resume_userspace": -+: "r"(current_thread_info()), -+ "ir"(THREAD_SIZE - 8 - sizeof(regs)), -+ "r"(®s), "ir"(sizeof(regs)) -+#ifdef _GCC444 -+: "$r0", "$r1", "$r2", "$r4", "$r5", "$r8", "$r9", "$p0", "$p1", -+ "memory"); -+#else -+: "$r0", "$r1", "$r2", "$r4", "$r5", "$r8", "$r9", "$r26", "$r27", -+ "memory"); -+#endif -+out: -+ return ret; -+} -+ -+EXPORT_SYMBOL(kernel_execve); -+ -+int sys_cacheflush(unsigned int start, unsigned int end) -+{ -+ struct vm_area_struct *vma; -+ -+ vma = find_vma(current->mm, start); -+ if (!vma) -+ return 0; -+ cpu_cache_wbinval_range_check(vma, start, end); -+ return 0; -+} -+ -+asmlinkage long sys_fadvise64_64_wrapper(int fd, int advice, loff_t offset, -+ loff_t len) -+{ -+ return sys_fadvise64_64(fd, offset, len, advice); -+} -+ -+asmlinkage int nds32_syscall(int number, struct pt_regs *regs) -+{ -+ switch (number) { -+ case 0x7000: /* cacheflush */ -+ return sys_cacheflush(regs->NDS32_r1, regs->NDS32_r2); -+ -+#ifdef CONFIG_OPROFILE -+ case __NR_pfmctl: -+ sys_pfmctl(regs->NDS32_r1, regs->NDS32_r2, regs->NDS32_r3, -+ regs->NDS32_r4); -+ return 0; -+ -+ case __NR_getpfm: -+ return sys_getpfm((struct pcounter __user *)regs->NDS32_r1); -+ -+ case __NR_setpfm: -+ return sys_setpfm(regs->NDS32_r1, regs->NDS32_r2, -+ regs->NDS32_r3, -+ (struct pcounter __user *)regs->NDS32_r4); -+#endif -+ case __NR_wbna: -+ if (regs->NDS32_r1) -+ regs->NDS32_ipsw |= PSW_mskWBNA; -+ else -+ regs->NDS32_ipsw &= ~PSW_mskWBNA; -+ return 0; -+ -+ default: -+ return -ENOSYS; -+ } -+ return -ENOSYS; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/time.c linux-3.4.113/arch/nds32/kernel/time.c ---- linux-3.4.113.orig/arch/nds32/kernel/time.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/time.c 2016-12-01 20:59:24.356612904 +0100 -@@ -0,0 +1,94 @@ -+/* -+ * linux/arch/nds32/kernel/time.c -+ * -+ * Copyright (C) 1991, 1992, 1995 Linus Torvalds -+ * Modifications for ARM (C) 1994-2001 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * This file contains the ARM-specific time handling details: -+ * reading the RTC at bootup, etc... -+ * -+ * 1994-07-02 Alan Modra -+ * fixed set_rtc_mmss, fixed time.year for >= 2000, new mktime -+ * 1998-12-20 Updated NTP code according to technical memorandum Jan '96 -+ * "A Kernel Model for Precision Timekeeping" by Dave Mills -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+/* -+ * Our system timer. -+ */ -+struct sys_timer *system_timer; -+ -+#ifdef CONFIG_SMP -+unsigned long profile_pc(struct pt_regs *regs) -+{ -+ unsigned long fp, pc = instruction_pointer(regs); -+ -+ if (in_lock_functions(pc)) { -+ fp = regs->NDS32_fp; -+ pc = ((unsigned long *)fp)[-1]; -+ } -+ -+ return pc; -+} -+ -+EXPORT_SYMBOL(profile_pc); -+#endif -+#if defined(CONFIG_PM) && !defined(CONFIG_GENERIC_CLOCKEVENTS) -+static int timer_suspend(void) -+{ -+ if (system_timer->suspend) -+ system_timer->suspend(); -+ -+ return 0; -+} -+ -+static void timer_resume(void) -+{ -+ if (system_timer->resume) -+ system_timer->resume(); -+} -+#else -+#define timer_suspend NULL -+#define timer_resume NULL -+#endif -+#ifdef CONFIG_ARCH_USES_GETTIMEOFFSET -+u32 arch_gettimeoffset(void) -+{ -+ if (system_timer->offset != NULL) -+ return system_timer->offset() * 1000; -+ -+ return 0; -+} -+#endif /* CONFIG_ARCH_USES_GETTIMEOFFSET */ -+static struct syscore_ops timer_syscore_ops = { -+ .suspend = timer_suspend, -+ .resume = timer_resume, -+}; -+ -+static int __init timer_init_syscore_ops(void) -+{ -+ register_syscore_ops(&timer_syscore_ops); -+ -+ return 0; -+} -+ -+device_initcall(timer_init_syscore_ops); -+ -+void __init time_init(void) -+{ -+ system_timer = machine_desc->timer; -+ system_timer->init(); // link to cpe_timer_init -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/traps.c linux-3.4.113/arch/nds32/kernel/traps.c ---- linux-3.4.113.orig/arch/nds32/kernel/traps.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/traps.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,733 @@ -+/* -+ * linux/arch/nds32/kernel/traps.c -+ * -+ * Copyright (C) 1995-2002 Russell King -+ * Fragments that appear the same as linux/arch/i386/kernel/traps.c (C) Linus Torvalds -+ * -+ * 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. -+ * -+ * 'traps.c' handles hardware exceptions after we have saved some state in -+ * 'linux/arch/nds32/lib/traps.S'. Mostly a debugging aid, but will probably -+ * kill the offending process. -+ */ -+/* ============================================================================ -+ * -+ * linux/arch/nds32/kernel/traps.c -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is trap handling for NDS32 core, initial refer from ARM. -+ * -+ * Revision History: -+ * -+ * Jul.16.2007 Initial ported by Tom, revised for KGDB by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include "ptrace.h" -+#include "signal.h" -+ -+extern void show_pte(struct mm_struct *mm, unsigned long addr); -+ -+#ifdef CONFIG_DEBUG_USER -+unsigned int user_debug; -+ -+static int __init user_debug_setup(char *str) -+{ -+ get_option(&str, &user_debug); -+ return 1; -+} -+ -+__setup("user_debug=", user_debug_setup); -+#endif -+ -+/* -+ * Dump out the contents of some memory nicely... -+ */ -+void dump_mem(const char *str, unsigned long bottom, unsigned long top) -+{ -+ unsigned long p = bottom & ~31; -+ mm_segment_t fs; -+ int i; -+ -+ /* -+ * We need to switch to kernel mode so that we can use __get_user -+ * to safely read from kernel space. Note that we now dump the -+ * code first, just in case the backtrace kills us. -+ */ -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ printk("%s(0x%08lx to 0x%08lx)\n", str, bottom, top); -+ -+ for (p = bottom & ~31; p < top;) { -+ printk("%04lx: ", p & 0xffff); -+ -+ for (i = 0; i < 8; i++, p += 4) { -+ unsigned int val; -+ -+ if (p < bottom || p >= top) -+ printk(" "); -+ else { -+ __get_user(val, (unsigned long *)p); -+ printk("%08x ", val); -+ } -+ } -+ printk("\n"); -+ } -+ -+ set_fs(fs); -+} -+ -+EXPORT_SYMBOL(dump_mem); -+ -+/* These intrinsic functions are not supported in V2 toolchains of BSP321. */ -+#ifndef __NDS32_BASELINE_V2__ -+#define DEBUG_TLB_CACHE -+#endif -+#ifdef DEBUG_TLB_CACHE -+/* This is the number of TLB entries. User should change it if necessary. */ -+#define TLB_NUM 128 -+unsigned int tlb_misc_new[TLB_NUM], tlb_vpn_new[TLB_NUM], tlb_data_new[TLB_NUM]; -+/* To get the whole TLB contents once it uses va=0x0 */ -+void dump_tlb(unsigned long va) -+{ -+ unsigned int rd_num, tlb_vpn, tlb_misc, tlb_data, mmu_cfg, tlb_num; -+ -+ /* save tlb system registers */ -+ tlb_vpn = __nds32__mfsr(NDS32_SR_TLB_VPN); -+ tlb_misc = __nds32__mfsr(NDS32_SR_TLB_MISC); -+ tlb_data = __nds32__mfsr(NDS32_SR_TLB_DATA); -+ mmu_cfg = __nds32__mfsr(NDS32_SR_MMU_CFG); -+ tlb_num = -+ (((mmu_cfg & MMU_CFG_mskTBW) >> MMU_CFG_offTBW) + -+ 1) * (1 << (((mmu_cfg & MMU_CFG_mskTBS) >> MMU_CFG_offTBS) + 2)); -+ -+ for (rd_num = 0; rd_num < tlb_num; rd_num++) { -+ /* read tlb entry with index */ -+ __nds32__tlbop_trd(rd_num); -+ __nds32__dsb(); -+ tlb_vpn_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_VPN); -+ tlb_misc_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_MISC); -+ tlb_data_new[rd_num] = __nds32__mfsr(NDS32_SR_TLB_DATA); -+ } -+ -+ /* restore tlb system registers */ -+ __nds32__mtsr(tlb_vpn, NDS32_SR_TLB_VPN); -+ __nds32__mtsr(tlb_misc, NDS32_SR_TLB_MISC); -+ __nds32__dsb(); -+ -+ printk("cur VPN:%08x, MISC:%08x, DATA:%08x\n", tlb_vpn, tlb_misc, -+ tlb_data); -+ /* to read out all the data */ -+ for (rd_num = 0; rd_num < tlb_num; rd_num++) { -+ /*unsigned int vpn = tlb_vpn_new[rd_num] & PAGE_MASK; */ -+ if (tlb_data_new[rd_num] & 0x1) -+ if (va == 0x0 -+ || (va != 0x0 -+ && (tlb_vpn_new[rd_num] == (va & PAGE_MASK)))) -+ printk -+ ("idx:0x%08x, VPN:%08x, MISC:%08x, DATA:%08x\n", -+ rd_num, tlb_vpn_new[rd_num], -+ tlb_misc_new[rd_num], -+ tlb_data_new[rd_num]); -+ } -+} -+ -+EXPORT_SYMBOL(dump_tlb); -+ -+struct cache_element { -+ unsigned int pa; -+ unsigned int wd; -+ unsigned int cacheline[8]; -+ unsigned char dirty; -+ unsigned char valid; -+ unsigned char lock; -+}; -+ -+/* This is the number of cache entries. User should change it if necessary. */ -+#define CACHE_SET_NUM 0x100 -+#define CACHE_WAY_NUM 0x4 -+volatile struct cache_element ce[CACHE_SET_NUM][CACHE_WAY_NUM]; -+#define CCTL_mskDIRTY 0x400000 -+#define CCTL_offDIRTY 22 -+#define CCTL_mskVALID 0x2 -+#define CCTL_offVALID 1 -+#define CCTL_mskLOCK 0x1 -+#define CCTL_offLOCK 0 -+#define CCTL_mskTAG 0x3ffffc -+#define CCTL_offTAG 0x2 -+extern unsigned long va2idx(unsigned long va, unsigned int cache_type, -+ unsigned long *way_offset); -+#include -+extern struct cache_info L1_cache_info[2]; -+void dump_cache(unsigned int cache_type) -+{ -+ volatile unsigned long idx, way, ra, tag, i; -+ unsigned long sets, ways, line_size, set_bits, way_bits, line_bits, -+ way_offset; -+ -+ ways = L1_cache_info[DCACHE].ways; -+ sets = L1_cache_info[DCACHE].sets; -+ set_bits = L1_cache_info[cache_type].set_bits; -+ way_bits = L1_cache_info[cache_type].way_bits; -+ line_bits = L1_cache_info[cache_type].line_bits; -+ line_size = L1_cache_info[cache_type].line_size; -+ way_offset = set_bits + line_bits; -+ -+ if (cache_type != ICACHE && cache_type != DCACHE) { -+ printk("%s not supported cache_type:%x\n", __func__, -+ cache_type); -+ return; -+ } -+ -+ /* NDS32_CCTL_L1I_IX_RTAG Read tag L1I cache */ -+ /* NDS32_CCTL_L1I_IX_RWD Read word data L1I cache */ -+ -+ for (idx = 0; idx < sets; idx++) { -+ for (way = 0; way < ways; way++) { -+ ra = (way << way_offset) | (idx << line_bits); -+ if (cache_type == ICACHE) -+ tag = -+ __nds32__cctlidx_read -+ (NDS32_CCTL_L1I_IX_RTAG, ra); -+ else -+ tag = -+ __nds32__cctlidx_read -+ (NDS32_CCTL_L1D_IX_RTAG, ra); -+ ce[idx][way].dirty = -+ (unsigned char)(tag & CCTL_mskDIRTY) >> -+ CCTL_offDIRTY; -+ ce[idx][way].valid = -+ (unsigned char)(tag & CCTL_mskVALID) >> -+ CCTL_offVALID; -+ ce[idx][way].lock = -+ (unsigned char)(tag & CCTL_mskLOCK) >> CCTL_offLOCK; -+ ce[idx][way].pa = -+ (tag & CCTL_mskTAG) >> CCTL_offTAG << PAGE_SHIFT; -+ for (i = 0; i < line_size / 4; i++) { -+ if (cache_type == ICACHE) -+ ce[idx][way].cacheline[i] = -+ __nds32__cctlidx_read -+ (NDS32_CCTL_L1I_IX_RWD, -+ (ra | i << 2)); -+ else -+ ce[idx][way].cacheline[i] = -+ __nds32__cctlidx_read -+ (NDS32_CCTL_L1D_IX_RWD, -+ (ra | i << 2)); -+ } -+ } -+ } -+ printk("dump %s\n", cache_type ? "DCACHE" : "ICACHE"); -+ printk("%8s %4s %4s %1s %1s %1s %8s %8s %8s %8s %8s %8s %8s %8s\n", -+ "ADDRESS", "SET", "WAY", "V", "D", "L", "00", "04", "08", "0C", -+ "10", "14", "18", "1C"); -+ for (idx = 0; idx < sets; idx++) { -+ for (way = 0; way < ways; way++) { -+ printk("%08lx %04lx %04lx %1u %1u %1u ", -+ ce[idx][way].pa + -+ ((idx * line_size) % PAGE_SIZE), idx, way, -+ ce[idx][way].valid, ce[idx][way].dirty, -+ ce[idx][way].lock); -+ for (i = 0; i < line_size / 4; i++) { -+ printk("%08x ", ce[idx][way].cacheline[i]); -+ } -+ printk("\n"); -+ } -+ } -+} -+ -+EXPORT_SYMBOL(dump_cache); -+ -+void dump_cache_va(unsigned int cache_type, unsigned int va) -+{ -+ volatile struct cache_element cache_entry[4]; -+ volatile unsigned long idx, way, tag, ra, i; -+ unsigned long ways, line_size, set_bits, line_bits, way_offset; -+ -+ ways = L1_cache_info[cache_type].ways; -+ line_size = CACHE_LINE_SIZE(cache_type); -+ set_bits = L1_cache_info[cache_type].set_bits; -+ line_bits = L1_cache_info[cache_type].line_bits; -+ -+ if (cache_type != ICACHE && cache_type != DCACHE) { -+ printk("%s not supported cache_type:%x\n", __func__, -+ cache_type); -+ return; -+ } -+ idx = va2idx(va, cache_type, &way_offset); -+ //idx = (va & (((1 << set_bits) - 1) << line_bits)) >> line_bits; -+ for (way = 0; way < ways; way++) { -+ ra = (way << way_offset) | idx; -+ if (cache_type == ICACHE) -+ tag = __nds32__cctlidx_read(NDS32_CCTL_L1I_IX_RTAG, ra); -+ else -+ tag = __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RTAG, ra); -+ cache_entry[way].dirty = -+ (unsigned char)(tag & CCTL_mskDIRTY) >> CCTL_offDIRTY; -+ cache_entry[way].valid = -+ (unsigned char)(tag & CCTL_mskVALID) >> CCTL_offVALID; -+ cache_entry[way].lock = -+ (unsigned char)(tag & CCTL_mskLOCK) >> CCTL_offLOCK; -+ cache_entry[way].pa = -+ (tag & CCTL_mskTAG) >> CCTL_offTAG << PAGE_SHIFT; -+ for (i = 0; i < line_size / 4; i++) { -+ if (cache_type == ICACHE) -+ cache_entry[way].cacheline[i] = -+ __nds32__cctlidx_read(NDS32_CCTL_L1I_IX_RWD, -+ (ra | i << 2)); -+ else -+ cache_entry[way].cacheline[i] = -+ __nds32__cctlidx_read(NDS32_CCTL_L1D_IX_RWD, -+ (ra | i << 2)); -+ } -+ } -+ printk("dump %s va:%x\n", cache_type ? "DCACHE" : "ICACHE", va); -+ -+ printk("%8s %4s %4s %1s %1s %1s %8s %8s %8s %8s %8s %8s %8s %8s\n", -+ "ADDRESS", "SET", "WAY", "V", "D", "L", "00", "04", "08", "0C", -+ "10", "14", "18", "1C"); -+ for (way = 0; way < ways; way++) { -+ printk("%08lx %04lx %04lx %1u %1u %1u ", -+ cache_entry[way].pa + -+ (((idx >> line_bits) * line_size) % PAGE_SIZE), -+ (idx >> line_bits), way, cache_entry[way].valid, -+ cache_entry[way].dirty, cache_entry[way].lock); -+ for (i = 0; i < 8; i++) { -+ printk("%08x ", cache_entry[way].cacheline[i]); -+ } -+ printk("\n"); -+ } -+} -+ -+EXPORT_SYMBOL(dump_cache_va); -+#endif -+ -+static void dump_instr(struct pt_regs *regs) -+{ -+ unsigned long addr = instruction_pointer(regs); -+ const int width = 8; -+ mm_segment_t fs; -+ int i; -+ -+ return; -+ /* -+ * We need to switch to kernel mode so that we can use __get_user -+ * to safely read from kernel space. Note that we now dump the -+ * code first, just in case the backtrace kills us. -+ */ -+ fs = get_fs(); -+ set_fs(KERNEL_DS); -+ -+ printk("Code: "); -+ for (i = -4; i < 1; i++) { -+ unsigned int val, bad; -+ -+ bad = __get_user(val, &((u32 *) addr)[i]); -+ -+ if (!bad) -+ printk(i == 0 ? "(%0*x) " : "%0*x ", width, val); -+ else { -+ printk("bad PC value."); -+ break; -+ } -+ } -+ printk("\n"); -+ -+ set_fs(fs); -+} -+ -+#define LOOP_TIMES (100) -+void dump_stack(void) -+{ -+ int cnt = LOOP_TIMES; -+#ifndef CONFIG_FRAME_POINTER -+ unsigned long *stack; -+ unsigned long addr; -+ -+ __asm__ __volatile__("\tori\t%0, $sp, #0\n":"=r"(stack)); -+ printk("Call Trace:\n"); -+ while (!kstack_end(stack)) { -+ addr = *stack++; -+ if (__kernel_text_address(addr)) { -+ printk("[<%08lx>] ", addr); -+ print_symbol("%s\n", addr); -+ } -+ cnt--; -+ if (cnt < 0) -+ break; -+ } -+ printk("\n"); -+#else -+ unsigned long *fpn; -+ __asm__ __volatile__("\tori\t%0, $fp, #0\n":"=r"(fpn)); -+ printk("Call Trace:\n"); -+ while (!kstack_end((void *)fpn) && !((unsigned long)fpn & 0x3) -+ && ((unsigned long)fpn >= TASK_SIZE)) { -+ unsigned long lpp, fpp; -+#if !defined(NDS32_ABI_2) -+ lpp = fpn[0]; -+ fpp = fpn[1]; -+#else -+ lpp = fpn[0]; -+ fpp = fpn[-1]; -+#endif -+ if (__kernel_text_address(lpp)) { -+ printk("[<%08lx>] ", lpp); -+ print_symbol("%s\n", lpp); -+ fpn = (unsigned long *)fpp; -+ } -+ cnt--; -+ if (cnt < 0) -+ break; -+ } -+ printk("\n"); -+#endif -+} -+ -+EXPORT_SYMBOL(dump_stack); -+ -+void show_stack(struct task_struct *tsk, unsigned long *sp) -+{ -+ unsigned long fp; -+ -+ if (!tsk) -+ tsk = current; -+ -+ if (tsk != current) -+ fp = thread_saved_fp(tsk); -+ else -+ asm("move %0, $fp":"=r"(fp)); -+ -+ dump_stack(); -+ barrier(); -+} -+ -+DEFINE_SPINLOCK(die_lock); -+ -+/* -+ * This function is protected against re-entrancy. -+ */ -+void die(const char *str, struct pt_regs *regs, int err) -+{ -+ struct task_struct *tsk = current; -+ static int die_counter; -+ -+ console_verbose(); -+ spin_lock_irq(&die_lock); -+ bust_spinlocks(1); -+ -+ printk("Internal error: %s: %x [#%d]\n", str, err, ++die_counter); -+ print_modules(); -+ printk("CPU: %i\n", smp_processor_id()); -+ show_regs(regs); -+ printk("Process %s (pid: %d, stack limit = 0x%p)\n", -+ tsk->comm, tsk->pid, task_thread_info(tsk) + 1); -+ -+ if (!user_mode(regs) || in_interrupt()) { -+ dump_mem("Stack: ", regs->NDS32_sp, -+ 8192 + (unsigned long)task_thread_info(tsk)); -+ dump_instr(regs); -+ dump_stack(); -+ } -+ -+ bust_spinlocks(0); -+ spin_unlock_irq(&die_lock); -+ do_exit(SIGSEGV); -+} -+ -+void die_if_kernel(const char *str, struct pt_regs *regs, int err) -+{ -+ if (user_mode(regs)) -+ return; -+ -+ die(str, regs, err); -+} -+ -+int bad_syscall(int n, struct pt_regs *regs) -+{ -+ struct thread_info *thread = current_thread_info(); -+ siginfo_t info; -+ -+ if (current->personality != PER_LINUX && thread->exec_domain->handler) { -+ thread->exec_domain->handler(n, regs); -+ return regs->NDS32_r0; -+ } -+#ifdef CONFIG_DEBUG_USER -+ if (user_debug & UDBG_SYSCALL) { -+ printk(KERN_ERR "[%d] %s: obsolete system call %08x.\n", -+ current->pid, current->comm, n); -+ dump_instr(regs); -+ } -+#endif -+ -+ info.si_signo = SIGILL; -+ info.si_errno = 0; -+ info.si_code = ILL_ILLTRP; -+ info.si_addr = (void __user *)instruction_pointer(regs) - 4; -+ -+ force_sig_info(SIGILL, &info, current); -+ die_if_kernel("Oops - bad syscall", regs, n); -+ return regs->NDS32_r0; -+} -+ -+void __pte_error(const char *file, int line, unsigned long val) -+{ -+ printk("%s:%d: bad pte %08lx.\n", file, line, val); -+} -+ -+void __pmd_error(const char *file, int line, unsigned long val) -+{ -+ printk("%s:%d: bad pmd %08lx.\n", file, line, val); -+} -+ -+void __pgd_error(const char *file, int line, unsigned long val) -+{ -+ printk("%s:%d: bad pgd %08lx.\n", file, line, val); -+} -+ -+extern char exception_vector[73][64]; -+void __init trap_init(void) -+{ -+ return; -+} -+ -+void __init early_trap_init(void) -+{ -+ unsigned long ivb = 0; -+ unsigned long base = 0xc0000000; -+ -+ memcpy((unsigned long *)base, (unsigned long *)exception_vector, -+ sizeof(exception_vector)); -+ ivb = __nds32__mfsr(NDS32_SR_IVB); -+#ifdef CONFIG_EVIC -+ __nds32__mtsr((ivb & ~IVB_mskESZ) | (2 << IVB_offESZ) | -+ (1 << IVB_offEVIC) | IVB_BASE, NDS32_SR_IVB); -+#else -+ /* Check platform support. */ -+# if defined (CONFIG_IVIC_INTC) -+ if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) >= 2) -+ panic -+ ("IVIC mode is not allowed on the platform with interrupt controller\n"); -+# elif defined(CONFIG_IVIC) -+ if (((ivb & IVB_mskNIVIC) >> IVB_offNIVIC) < 2) -+ panic -+ ("IVIC mode is not allowed on the platform without interrupt controller\n"); -+# endif -+ __nds32__mtsr((ivb & ~IVB_mskESZ) | (2 << IVB_offESZ) | IVB_BASE, -+ NDS32_SR_IVB); -+#endif -+ __nds32__mtsr(0x10003, NDS32_SR_INT_MASK); -+ /* -+ * Copy signal return handlers into the vector page, and -+ * set sigreturn to be a pointer to these. -+ */ -+ memcpy((void *)KERN_SIGRETURN_CODE, retcodes, sizeof(retcodes)); -+ memcpy((void *)KERN_RESTART_CODE, syscall_restart_code, -+ sizeof(syscall_restart_code)); -+ -+ /* -+ * 0x2000 is 8K-aligned of 0x1240 = 73 vectors * 64byte -+ * 0x1000 is page saving sigreturn & restart code -+ */ -+ flush_icache_range(base, base + 0x3000); -+} -+ -+#if 0 -+COLE:use send_sigtrap instread -+ static __inline__ void do_trap(int trapnr, int signr, const char *str, -+ struct pt_regs *regs, -+ unsigned long error_code, siginfo_t * info) -+{ -+ if (user_mode(regs)) { -+ /* trap_signal */ -+ struct task_struct *tsk = current; -+ tsk->thread.error_code = error_code; -+ tsk->thread.trap_no = trapnr; -+ if (info) -+ force_sig_info(signr, info, tsk); -+ else -+ force_sig(signr, tsk); -+ return; -+ } else { -+ /* kernel_trap */ -+ if (!fixup_exception(regs)) -+ die(str, regs, error_code); -+ return; -+ } -+} -+#endif -+ -+/* -+ * I modified original debug_trap to apply KGDB stuff, -+ * Harry@Jul.18.2007 -+ */ -+void do_debug_trap(unsigned long entry, unsigned long addr, -+ unsigned long type, struct pt_regs *regs) -+{ -+ if (notify_die(DIE_DEBUG, "debug", regs, addr, type, SIGTRAP) -+ == NOTIFY_STOP) -+ return; -+ -+#if !defined(CONFIG_HSS) -+ /* clear the swbk; otherwise the user will see it */ -+ if (test_tsk_thread_flag(current, TIF_SINGLESTEP)) -+ ptrace_cancel_swbk(current); -+#endif -+ -+ /* do_trap(1, SIGTRAP, 0, regs, 0, NULL); */ -+ if (user_mode(regs)) { -+ /* trap_signal */ -+ send_sigtrap(current, regs, 0, TRAP_BRKPT); -+ } else { -+ /* kernel_trap */ -+ if (!fixup_exception(regs)) -+ die("unexpected kernel_trap", regs, 0); -+ } -+} -+ -+void unhandled_interruption(struct pt_regs *regs) -+{ -+ siginfo_t si; -+ printk("unhandled_interruption\n"); -+ show_regs(regs); -+ if (!user_mode(regs)) -+ do_exit(SIGKILL); -+ si.si_signo = SIGKILL; -+ si.si_errno = 0; -+ force_sig_info(SIGKILL, &si, current); -+} -+ -+void unhandled_exceptions(unsigned long entry, unsigned long addr, -+ unsigned long type, struct pt_regs *regs) -+{ -+ siginfo_t si; -+ printk("Unhandled Exception: entry: %lx addr:%lx itype:%lx\n", entry, -+ addr, type); -+ show_regs(regs); -+ if (!user_mode(regs)) -+ do_exit(SIGKILL); -+ si.si_signo = SIGKILL; -+ si.si_errno = 0; -+ si.si_addr = (void *)addr; -+ force_sig_info(SIGKILL, &si, current); -+} -+ -+extern int do_page_fault(unsigned long entry, unsigned long addr, -+ unsigned int error_code, struct pt_regs *regs); -+ -+/* -+ * 2:DEF dispatch for TLB MISC exception handler -+*/ -+ -+void do_dispatch_tlb_misc(unsigned long entry, unsigned long addr, -+ unsigned long type, struct pt_regs *regs) -+{ -+ type = type & (ITYPE_mskINST | ITYPE_mskETYPE); -+ if ((type & 0xf) < 5) -+ do_page_fault(entry, addr, type, regs); -+ else -+ unhandled_exceptions(entry, addr, type, regs); -+} -+ -+int (*do_unaligned_access) (unsigned long entry, unsigned long addr, -+ unsigned long type, struct pt_regs * regs) = NULL; -+ -+EXPORT_SYMBOL(do_unaligned_access); -+ -+void do_revinsn(struct pt_regs *regs) -+{ -+ siginfo_t si; -+ printk("Reserved Instruction\n"); -+ show_regs(regs); -+ if (!user_mode(regs)) -+ do_exit(SIGILL); -+ si.si_signo = SIGILL; -+ si.si_errno = 0; -+ force_sig_info(SIGILL, &si, current); -+} -+ -+/* -+ * 7:DEF dispatch for General exception handler -+ */ -+void do_dispatch_general(unsigned long entry, unsigned long addr, -+ unsigned long itype, struct pt_regs *regs, -+ unsigned long oipc) -+{ -+ unsigned int swid = itype >> ITYPE_offSWID; -+ unsigned long type = itype & (ITYPE_mskINST | ITYPE_mskETYPE); -+ if (type == 0) { /* Alignment check */ -+ -+ if (do_unaligned_access) { -+ -+ int ret = do_unaligned_access(entry, addr, type, regs); -+ -+ if (ret == 0) -+ return; -+ -+ if (ret == -EFAULT) -+ printk -+ ("Unhandled unaligned access exception\n"); -+ } -+ do_page_fault(entry, addr, type, regs); -+ } else if (type == 1) /* Reserved instruction */ -+ do_revinsn(regs); -+ else if (type == 6) { /* Coprocessor */ -+ if (((GET_ITYPE() & ITYPE_mskSTYPE) >> ITYPE_offSTYPE) == 3) { -+#ifdef CONFIG_AUDIO -+ preempt_disable(); -+ do_audio_context_switch(type, regs); -+ preempt_enable(); -+#else -+ unhandled_exceptions(entry, addr, type, regs); -+#endif -+ } else { -+#ifdef CONFIG_FPU -+ do_fpu_exception(type, regs); -+#else -+ unhandled_exceptions(entry, addr, type, regs); -+#endif -+ } -+ } else if (type == 2 && swid == 0x1a) { -+ /* trap, used on v3 EDM target debugging workaround */ -+ /* -+ * DIPC(OIPC) is passed as parameter before -+ * interrupt is enabled, so the DIPC will not be corrupted -+ * even though interrupts are coming in -+ */ -+ /* -+ * 1. update ipc -+ * 2. update pt_regs ipc with oipc -+ * 3. update pt_regs ipsw (clear DEX) -+ */ -+ __asm__ volatile ("mtsr %0, $IPC\n\t"::"r" (oipc)); -+ regs->NDS32_ipc = oipc; -+ regs->NDS32_ipsw &= ~0x400; -+ do_debug_trap(entry, addr, itype, regs); -+ } else -+ unhandled_exceptions(entry, addr, type, regs); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/kernel/vmlinux.lds.S linux-3.4.113/arch/nds32/kernel/vmlinux.lds.S ---- linux-3.4.113.orig/arch/nds32/kernel/vmlinux.lds.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/kernel/vmlinux.lds.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,74 @@ -+#include -+#include -+#include -+#include -+ -+#define LOAD_OFFSET (PAGE_OFFSET - PHYS_OFFSET) -+#include -+ -+OUTPUT_ARCH(nds32) -+ENTRY(_stext_lma) -+jiffies = jiffies_64; -+ -+SECTIONS -+{ -+ _stext_lma = TEXTADDR - LOAD_OFFSET; -+ . = TEXTADDR; -+ __init_begin = .; -+ HEAD_TEXT_SECTION -+ INIT_TEXT_SECTION(PAGE_SIZE) -+ /* These sections are arch specific. */ -+ .arch_info : AT(ADDR(.arch_info) - LOAD_OFFSET) { -+ . = ALIGN(4); -+ VMLINUX_SYMBOL(__proc_info_begin) = .; -+ *(.proc.info.init) -+ VMLINUX_SYMBOL(__proc_info_end) = .; -+ __arch_info_begin = .; -+ *(.arch.info) -+ __arch_info_end = .; -+ __tagtable_begin = .; -+ *(.taglist) -+ __tagtable_end = .; -+ . = ALIGN(16); -+ __pv_table_begin = .; -+ *(.pv_table) -+ __pv_table_end = .; -+ __early_begin = .; -+ *(__early_param) -+ __early_end = .; -+ } -+ -+ INIT_DATA_SECTION(16) -+ PERCPU_SECTION(L1_CACHE_BYTES) -+ __init_end = .; -+ -+ . = ALIGN(PAGE_SIZE); -+ _stext = .; -+ /* Real text segment */ -+ .text : AT(ADDR(.text) - LOAD_OFFSET) { -+ _text = .; /* Text and read-only data */ -+ TEXT_TEXT -+ SCHED_TEXT -+ LOCK_TEXT -+ KPROBES_TEXT -+ IRQENTRY_TEXT -+ *(.fixup) -+ } -+ -+ _etext = .; /* End of text and rodata section */ -+ -+ _sdata = .; -+ RO_DATA_SECTION(PAGE_SIZE) -+ RW_DATA_SECTION(L1_CACHE_BYTES, PAGE_SIZE, THREAD_SIZE) -+ _edata = .; -+ -+ EXCEPTION_TABLE(16) -+ NOTES -+ BSS_SECTION(4, 4, 4) -+ _end = .; -+ -+ STABS_DEBUG -+ DWARF_DEBUG -+ -+ DISCARDS -+} -diff -Nur linux-3.4.113.orig/arch/nds32/lib/copy_page.S linux-3.4.113/arch/nds32/lib/copy_page.S ---- linux-3.4.113.orig/arch/nds32/lib/copy_page.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/copy_page.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * linux/arch/nds32/lib/copypage.S -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+#include -+#include -+ -+ .text -+ENTRY(copy_page) -+ pushm $r2, $r10 -+ movi $r2, PAGE_SIZE >> 5 -+.Lcopy_loop: -+ lmw.bim $r3, [$r1], $r10 -+ smw.bim $r3, [$r0], $r10 -+ subi45 $r2, #1 -+ bnez38 $r2, .Lcopy_loop -+ popm $r2, $r10 -+ ret -+ -+ENTRY(clear_page) -+ pushm $r1, $r9 -+ movi $r1, PAGE_SIZE >> 5 -+ movi55 $r2, #0 -+ movi55 $r3, #0 -+ movi55 $r4, #0 -+ movi55 $r5, #0 -+ movi55 $r6, #0 -+ movi55 $r7, #0 -+ movi55 $r8, #0 -+ movi55 $r9, #0 -+.Lclear_loop: -+ smw.bim $r2, [$r0], $r9 -+ subi45 $r1, #1 -+ bnez38 $r1, .Lclear_loop -+ popm $r1, $r9 -+ ret -diff -Nur linux-3.4.113.orig/arch/nds32/lib/csum_partial.c linux-3.4.113/arch/nds32/lib/csum_partial.c ---- linux-3.4.113.orig/arch/nds32/lib/csum_partial.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/csum_partial.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,135 @@ -+/* -+ * INET An implementation of the TCP/IP protocol suite for the LINUX -+ * operating system. INET is implemented using the BSD Socket -+ * interface as the means of communication with the user level. -+ * -+ * MIPS specific IP/TCP/UDP checksumming routines -+ * -+ * Authors: Ralf Baechle, -+ * Lots of code moved from tcp.c and ip.c; see those files -+ * for more names. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#define addc(_t,_r) \ -+ __asm__ __volatile__ ( \ -+ "add\t%0, %0, %1\n\t" \ -+ "slt\t$p1, %0, %1\n\t" \ -+ "add\r%0, %0, $p1\n\t" \ -+ : "=r"(_t) \ -+ : "r"(_r), "0"(_t)); -+ -+static inline unsigned short from32to16(unsigned int x) -+{ -+ /* 32 bits --> 16 bits + carry */ -+ x = (x & 0xffff) + (x >> 16); -+ /* 16 bits + carry --> 16 bits including carry */ -+ x = (x & 0xffff) + (x >> 16); -+ return (unsigned short)x; -+} -+ -+static inline unsigned int do_csum(const unsigned char *buff, int len) -+{ -+ int odd; -+ register unsigned int result = 0; -+ register unsigned int count; -+ if (len <= 0) -+ goto out; -+ odd = 1 & (unsigned long)buff; -+ if (odd) { -+ result = be16_to_cpu(*buff); -+ len--; -+ buff++; -+ } -+ count = len >> 1; /* nr of 16-bit words.. */ -+ if (count) { -+ if (2 & (unsigned long)buff) { -+ result += *(unsigned short *)buff; -+ count--; -+ len -= 2; -+ buff += 2; -+ } -+ count >>= 1; /* nr of 32-bit words.. */ -+ if (count) { -+ while (count >= 8) { -+ __asm__ -+ __volatile__("lmw.bi $r17, [%1], $r24\n\t" -+ "add\t%0, %0, $r17\n\t" -+ "slt\t$p1, %0, $r17\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r18\n\t" -+ "slt\t$p1, %0, $r18\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r19\n\t" -+ "slt\t$p1, %0, $r19\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r20\n\t" -+ "slt\t$p1, %0, $r20\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r21\n\t" -+ "slt\t$p1, %0, $r21\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r22\n\t" -+ "slt\t$p1, %0, $r22\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r23\n\t" -+ "slt\t$p1, %0, $r23\n\t" -+ "add\r%0, %0, $p1\n\t" -+ "add\t%0, %0, $r24\n\t" -+ "slt\t$p1, %0, $r24\n\t" -+ "add\r%0, %0, $p1\n\t":"=r" -+ (result) -+ :"r"(buff), "0"(result) -+ :"$r17", "$r18", "$r19", -+ "$r20", "$r21", "$r22", "$r23", -+ "$r24"); -+ count -= 8; -+ buff += 32; -+ } -+ while (count) { -+ unsigned int w = *(unsigned int *)buff; -+ count--; -+ buff += 4; -+ addc(result, w); -+ } -+ result = (result & 0xffff) + (result >> 16); -+ } -+ if (len & 2) { -+ result += *(unsigned short *)buff; -+ buff += 2; -+ } -+ } -+ if (len & 1) -+ result += le16_to_cpu(*buff); -+ result = from32to16(result); -+ if (odd) -+ result = swab16(result); -+out: -+ return result; -+} -+ -+/* -+ * computes a partial checksum, e.g. for TCP/UDP fragments -+ */ -+/* -+ * why bother folding? -+ */ -+unsigned int csum_partial(const void *buff, int len, unsigned int sum) -+{ -+ unsigned int result = 0; -+// printk("csum_partial %x %x %x\n", buff, len, sum); -+ result = do_csum(buff, len); -+ addc(result, sum); -+ return (unsigned short)from32to16(result); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/lib/csum_partial_copy.c linux-3.4.113/arch/nds32/lib/csum_partial_copy.c ---- linux-3.4.113.orig/arch/nds32/lib/csum_partial_copy.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/csum_partial_copy.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,58 @@ -+/* -+ * INET An implementation of the TCP/IP protocol suite for the LINUX -+ * operating system. INET is implemented using the BSD Socket -+ * interface as the means of communication with the user level. -+ * -+ * MIPS specific IP/TCP/UDP checksumming routines -+ * -+ * Authors: Ralf Baechle, -+ * Lots of code moved from tcp.c and ip.c; see those files -+ * for more names. -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License -+ * as published by the Free Software Foundation; either version -+ * 2 of the License, or (at your option) any later version. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * copy while checksumming, otherwise like csum_partial -+ */ -+unsigned int csum_partial_copy_nocheck(const unsigned char *src, -+ unsigned char *dst, int len, -+ unsigned int sum) -+{ -+ /* -+ * It's 2:30 am and I don't feel like doing it real ... -+ * This is lots slower than the real thing (tm) -+ */ -+ sum = csum_partial(src, len, sum); -+ memcpy(dst, src, len); -+ -+ return sum; -+} -+ -+/* -+ * Copy from userspace and compute checksum. If we catch an exception -+ * then zero the rest of the buffer. -+ */ -+unsigned int csum_partial_copy_from_user(const unsigned char *src, -+ unsigned char *dst, int len, -+ unsigned int sum, int *err_ptr) -+{ -+ int missing; -+ -+ missing = copy_from_user(dst, src, len); -+ if (missing) { -+ memset(dst + len - missing, 0, missing); -+ *err_ptr = -EFAULT; -+ } -+ -+ return csum_partial(dst, len, sum); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/lib/divmod.c linux-3.4.113/arch/nds32/lib/divmod.c ---- linux-3.4.113.orig/arch/nds32/lib/divmod.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/divmod.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,46 @@ -+extern unsigned long udivmodsi4(unsigned long num, unsigned long den, -+ int modwanted); -+ -+long __divsi3(long a, long b) -+{ -+ int neg = 0; -+ long res; -+ -+ if (a < 0) { -+ a = -a; -+ neg = !neg; -+ } -+ -+ if (b < 0) { -+ b = -b; -+ neg = !neg; -+ } -+ -+ res = udivmodsi4(a, b, 0); -+ -+ if (neg) -+ res = -res; -+ -+ return res; -+} -+ -+long __modsi3(long a, long b) -+{ -+ int neg = 0; -+ long res; -+ -+ if (a < 0) { -+ a = -a; -+ neg = 1; -+ } -+ -+ if (b < 0) -+ b = -b; -+ -+ res = udivmodsi4(a, b, 1); -+ -+ if (neg) -+ res = -res; -+ -+ return res; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/lib/findbit.S linux-3.4.113/arch/nds32/lib/findbit.S ---- linux-3.4.113.orig/arch/nds32/lib/findbit.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/findbit.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,108 @@ -+/* -+ * linux/arch/nds32/lib/findbit.S -+ * -+ * Copyright (C) 1995-2000 Russell King -+ * Copyright (C) 2006 Andes Technology Corporation -+ * -+ * 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 -+ -+ .text -+ -+/* -+ * Purpose : Find a 'zero' bit -+ * Prototype: int find_first_zero_bit(void *addr, int maxbit); -+ */ -+ENTRY(_find_first_zero_bit) -+ move $r2, #0 -+ move $p0, #0 ! Reset bit count -+next_word: -+ move $r4, #4 -+ lmw.bim $p1, [$r0], $p1 -+ li $r3, #0xffffffff ! Inversion mask -+ xor $p1, $p1, $r3 ! Inverted the word -+ addi $p0, $p0, #32 -+ beqz $p1, next_word -+ addi $p0, $p0, #-32 -+next_byte: -+ beqz $r4, next_word -+ andi $r3, $p1, #0xff ! Get the next byte -+ bnez $r3, found ! Found zero bit in this byte -+ addi $p0, $p0, #8 ! Update bit count -+ addi $r4, $r4, #-1 -+ srli $p1, $p1, #8 -+ bgt $r1, $p0, next_byte -+ addi $r0, $r1, #1 ! Return not found -+ ret -+ -+/* -+ * Purpose : Find next 'zero' bit -+ * Prototype: int find_next_zero_bit(void *addr, int maxbit, int offset) -+ */ -+ENTRY(_find_next_zero_bit) -+ beqz $r2, _find_first_zero_bit ! If offset=0, goto find_first_zero_bit -+ srli $p0, $r2, #5 ! Get offset byte count -+ slli $p0, $p0, #2 -+ add $r0, $r0, $p0 ! $r0 is the first word to load -+ lmw.bim $p1, [$r0], $p1 -+ li $p0, #0xffffffff ! Inversion mask -+ xor $p1, $p1, $p0 ! Inverted the word -+ andi $r4, $r2, #31 ! Left bits in offset -+ srl $p1, $p1, $r4 ! Shift out the left bits -+ xor $p0, $p0, $p0 -+ subri $r4, $r4, #31 -+loop: -+ andi $r3, $p1, #0xff ! The first byte to check -+ bnez $r3, found ! Found zero bit in this byte -+ addi $p0, $p0, #8 -+ addi $r4, $r4, #-8 -+ srli $p1, $p1, #8 ! Move on to the next byte -+ bgtz $r4, loop -+ b next_word -+ -+/* -+ * One or more bits in the LSB of $p1 are assumed to be set. -+ */ -+ -+found: -+ move $p1, $r3 -+ xor $r4, $r4, $r4 -+ andi $r5, $p1, #0x0f ! Get bits 0-3 -+ move $r3, #4 ! For 0 case (no set bit found) -+ cmovn $r3, $r4, $r5 ! Not 0 case (There's set bit in these 4 bits) -+ add $p0, $p0, $r3 ! Update bit count -+ slli $r3, $p1, #4 ! Not 0 case (Find set bit in these 4 bits) -+ cmovn $p1, $r3, $r5 ! For 0 case (Find set bit in the rest 4 bits) -+ andi $r5, $p1, #0x30 ! Get 4-5 -+ move $r3, #2 ! For 0 case (no set bit found) -+ cmovn $r3, $r4, $r5 ! Not 0 case (There's set bit in these 2 bits) -+ add $p0, $p0, $r3 ! Update bit count -+ slli $r3, $p1, #2 ! Not 0 case (Find set bit in these 2 bits) -+ cmovn $p1, $r3, $r5 ! For 0 case (Find set bit in the rest 2 bits) -+ andi $r5, $p1, #0x40 ! Get bit 6 -+ move $r3, #1 ! For 0 case (bit 6 is not set) -+ cmovn $r3, $r4, $r5 ! Not 0 case (bit 6 is set bit) -+ add $r5, $p0, $r3 -+ add $r0, $r5, $r2 -+ ret -+ -+ENTRY(_ext2_find_first_zero_bit) -+ pushm $r2, $r4 -+ move $r2, #0 -+ move $p0, #0 ! Reset bit count -+1: -+ lbi.bi $r3, [$r0], #1 -+ xori $r3, $r3, #0xff -+ addi $p0, $p0, #8 -+ beqz $r3, 1b -+ addi $p0, $p0, #-8 -+ -+2: -+ b found ! No return -+ popm $r2, $r4 -+ ret -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/getuser.S linux-3.4.113/arch/nds32/lib/getuser.S ---- linux-3.4.113.orig/arch/nds32/lib/getuser.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/getuser.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,79 @@ -+/* -+ * linux/arch/nds32/lib/getuser.S -+ * -+ * Copyright (C) 2001 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds -+ * -+ * These functions have a non-standard call interface to make them more -+ * efficient, especially as they return an error value in addition to -+ * the "real" return value. -+ * -+ * __get_user_X -+ * -+ * Inputs: $r0 contains the address -+ * Outputs: $r0 is the error code -+ * $r2, $r3 contains the zero-extended value -+ * lr corrupted -+ * -+ * No other registers must be altered. (see include/asm-nds32/uaccess.h -+ * for specific ASM register usage). -+ * -+ * Note that ADDR_LIMIT is either 0 or 0xc0000000. -+ * Note also that it is intended that __get_user_bad is not global. -+ */ -+#include -+#include -+#include -+#include -+ -+ -+ENTRY(__get_user_1) -+1: lbi $r2, [$r0] -+ move $r0, #0 -+ ret -+ -+ENTRY(__get_user_2) -+2: lbi.bi $r2, [$r0], #1 -+3: lbi $r3, [$r0] -+#ifndef __NDS32_EB__ -+ slli $p1, $r3, #8 -+ or $r2, $r2, $p1 -+#else -+ slli $p1, $r2, #8 -+ or $r2, $r3, $p1 -+#endif -+ move $r0, #0 -+ ret -+ -+ENTRY(__get_user_4) -+4: lwi $r2, [$r0] -+ move $r0, #0 -+ ret -+ -+ENTRY(__get_user_8) -+5: lwi.bi $r2, [$r0], #4 -+6: lwi $r3, [$r0] -+ move $r0, #0 -+ ret -+ -+__get_user_bad_8: -+ move $r3, #0 -+__get_user_bad: -+ move $r2, #0 -+ move $r0, #-EFAULT -+ ret -+ -+.section __ex_table, "a" -+ .long 1b, __get_user_bad -+ .long 2b, __get_user_bad -+ .long 3b, __get_user_bad -+ .long 4b, __get_user_bad -+ .long 5b, __get_user_bad_8 -+ .long 6b, __get_user_bad_8 -+.previous -diff -Nur linux-3.4.113.orig/arch/nds32/lib/libgcc2.c linux-3.4.113/arch/nds32/lib/libgcc2.c ---- linux-3.4.113.orig/arch/nds32/lib/libgcc2.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/libgcc2.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,351 @@ -+#define BITS_PER_UNIT 8 -+#include "longlong.h" -+typedef unsigned int UQItype __attribute__ ((mode(QI))); -+typedef int SItype __attribute__ ((mode(SI))); -+typedef unsigned int USItype __attribute__ ((mode(SI))); -+typedef int DItype __attribute__ ((mode(DI))); -+typedef unsigned int UDItype __attribute__ ((mode(DI))); -+ -+typedef int word_type __attribute__ ((mode(__word__))); -+ -+#define Wtype SItype -+#define UWtype USItype -+#define DWtype DItype -+#define UDWtype UDItype -+ -+#ifdef __NDS32_EB__ -+struct DWstruct { -+ Wtype high, low; -+}; -+#else -+struct DWstruct { -+ Wtype low, high; -+}; -+#endif -+ -+typedef union { -+ struct DWstruct s; -+ DWtype ll; -+} DWunion; -+DWtype __negdi2(DWtype u) -+{ -+ const DWunion uu = {.ll = u }; -+ const DWunion w = { {.low = -uu.s.low, -+ .high = -uu.s.high - ((UWtype) - uu.s.low > 0)} -+ }; -+ -+ return w.ll; -+} -+ -+DWtype __lshrdi3(DWtype u, word_type b) -+{ -+ const DWunion uu = {.ll = u }; -+ const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b; -+ DWunion w; -+ -+ if (b == 0) -+ return u; -+ -+ if (bm <= 0) { -+ w.s.high = 0; -+ w.s.low = (UWtype) uu.s.high >> -bm; -+ } else { -+ const UWtype carries = (UWtype) uu.s.high << bm; -+ -+ w.s.high = (UWtype) uu.s.high >> b; -+ w.s.low = ((UWtype) uu.s.low >> b) | carries; -+ } -+ -+ return w.ll; -+} -+ -+DWtype __ashldi3(DWtype u, word_type b) -+{ -+ const DWunion uu = {.ll = u }; -+ const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b; -+ DWunion w; -+ -+ if (b == 0) -+ return u; -+ -+ if (bm <= 0) { -+ w.s.low = 0; -+ w.s.high = (UWtype) uu.s.low << -bm; -+ } else { -+ const UWtype carries = (UWtype) uu.s.low >> bm; -+ -+ w.s.low = (UWtype) uu.s.low << b; -+ w.s.high = ((UWtype) uu.s.high << b) | carries; -+ } -+ -+ return w.ll; -+} -+ -+DWtype __ashrdi3(DWtype u, word_type b) -+{ -+ const DWunion uu = {.ll = u }; -+ const word_type bm = (sizeof(Wtype) * BITS_PER_UNIT) - b; -+ DWunion w; -+ -+ if (b == 0) -+ return u; -+ -+ if (bm <= 0) { -+ /* w.s.high = 1..1 or 0..0 */ -+ w.s.high = uu.s.high >> (sizeof(Wtype) * BITS_PER_UNIT - 1); -+ w.s.low = uu.s.high >> -bm; -+ } else { -+ const UWtype carries = (UWtype) uu.s.high << bm; -+ -+ w.s.high = uu.s.high >> b; -+ w.s.low = ((UWtype) uu.s.low >> b) | carries; -+ } -+ -+ return w.ll; -+} -+ -+DWtype __muldi3(DWtype u, DWtype v) -+{ -+ const DWunion uu = {.ll = u }; -+ const DWunion vv = {.ll = v }; -+ DWunion w = {.ll = __umulsidi3(uu.s.low, vv.s.low) }; -+ -+ w.s.high += ((UWtype) uu.s.low * (UWtype) vv.s.high -+ + (UWtype) uu.s.high * (UWtype) vv.s.low); -+ -+ return w.ll; -+} -+ -+const UQItype __clz_tab[] = { -+ 0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4, 5, 5, 5, 5, 5, 5, 5, 5, -+ 5, 5, 5, 5, 5, 5, 5, 5, -+ 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, -+ 6, 6, 6, 6, 6, 6, 6, 6, -+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -+ 7, 7, 7, 7, 7, 7, 7, 7, -+ 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, -+ 7, 7, 7, 7, 7, 7, 7, 7, -+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, -+ 8, 8, 8, 8, 8, 8, 8, 8, -+}; -+ -+UDWtype __udivmoddi4(UDWtype n, UDWtype d, UDWtype * rp) -+{ -+ const DWunion nn = {.ll = n }; -+ const DWunion dd = {.ll = d }; -+ DWunion rr; -+ UWtype d0, d1, n0, n1, n2; -+ UWtype q0, q1; -+ UWtype b, bm; -+ DWunion ww; -+ -+ d0 = dd.s.low; -+ d1 = dd.s.high; -+ n0 = nn.s.low; -+ n1 = nn.s.high; -+ -+#if !UDIV_NEEDS_NORMALIZATION -+ if (d1 == 0) { -+ if (d0 > n1) { -+ /* 0q = nn / 0D */ -+ -+ udiv_qrnnd(q0, n0, n1, n0, d0); -+ q1 = 0; -+ -+ /* Remainder in n0. */ -+ } else { -+ /* qq = NN / 0d */ -+ -+ if (d0 == 0) -+ d0 = 1 / d0; /* Divide intentionally by zero. */ -+ -+ udiv_qrnnd(q1, n1, 0, n1, d0); -+ udiv_qrnnd(q0, n0, n1, n0, d0); -+ -+ /* Remainder in n0. */ -+ } -+ -+ if (rp != 0) { -+ rr.s.low = n0; -+ rr.s.high = 0; -+ *rp = rr.ll; -+ } -+ } -+#else /* UDIV_NEEDS_NORMALIZATION */ -+ -+ if (d1 == 0) { -+ if (d0 > n1) { -+ /* 0q = nn / 0D */ -+ -+ count_leading_zeros(bm, d0); -+ -+ if (bm != 0) { -+ /* Normalize, i.e. make the most significant bit of the -+ denominator set. */ -+ -+ d0 = d0 << bm; -+ n1 = (n1 << bm) | (n0 >> (W_TYPE_SIZE - bm)); -+ n0 = n0 << bm; -+ } -+ -+ udiv_qrnnd(q0, n0, n1, n0, d0); -+ q1 = 0; -+ -+ /* Remainder in n0 >> bm. */ -+ } else { -+ /* qq = NN / 0d */ -+ -+ if (d0 == 0) -+ d0 = 1 / d0; /* Divide intentionally by zero. */ -+ -+ count_leading_zeros(bm, d0); -+ -+ if (bm == 0) { -+ /* From (n1 >= d0) /\ (the most significant bit of d0 is set), -+ conclude (the most significant bit of n1 is set) /\ (the -+ leading quotient digit q1 = 1). -+ -+ This special case is necessary, not an optimization. -+ (Shifts counts of W_TYPE_SIZE are undefined.) */ -+ -+ n1 -= d0; -+ q1 = 1; -+ } else { -+ /* Normalize. */ -+ -+ b = W_TYPE_SIZE - bm; -+ -+ d0 = d0 << bm; -+ n2 = n1 >> b; -+ n1 = (n1 << bm) | (n0 >> b); -+ n0 = n0 << bm; -+ -+ udiv_qrnnd(q1, n1, n2, n1, d0); -+ } -+ -+ /* n1 != d0... */ -+ -+ udiv_qrnnd(q0, n0, n1, n0, d0); -+ -+ /* Remainder in n0 >> bm. */ -+ } -+ -+ if (rp != 0) { -+ rr.s.low = n0 >> bm; -+ rr.s.high = 0; -+ *rp = rr.ll; -+ } -+ } -+#endif /* UDIV_NEEDS_NORMALIZATION */ -+ -+ else { -+ if (d1 > n1) { -+ /* 00 = nn / DD */ -+ -+ q0 = 0; -+ q1 = 0; -+ -+ /* Remainder in n1n0. */ -+ if (rp != 0) { -+ rr.s.low = n0; -+ rr.s.high = n1; -+ *rp = rr.ll; -+ } -+ } else { -+ /* 0q = NN / dd */ -+ -+ count_leading_zeros(bm, d1); -+ if (bm == 0) { -+ /* From (n1 >= d1) /\ (the most significant bit of d1 is set), -+ conclude (the most significant bit of n1 is set) /\ (the -+ quotient digit q0 = 0 or 1). -+ -+ This special case is necessary, not an optimization. */ -+ -+ /* The condition on the next line takes advantage of that -+ n1 >= d1 (true due to program flow). */ -+ if (n1 > d1 || n0 >= d0) { -+ q0 = 1; -+ sub_ddmmss(n1, n0, n1, n0, d1, d0); -+ } else -+ q0 = 0; -+ -+ q1 = 0; -+ -+ if (rp != 0) { -+ rr.s.low = n0; -+ rr.s.high = n1; -+ *rp = rr.ll; -+ } -+ } else { -+ UWtype m1, m0; -+ /* Normalize. */ -+ -+ b = W_TYPE_SIZE - bm; -+ -+ d1 = (d1 << bm) | (d0 >> b); -+ d0 = d0 << bm; -+ n2 = n1 >> b; -+ n1 = (n1 << bm) | (n0 >> b); -+ n0 = n0 << bm; -+ -+ udiv_qrnnd(q0, n1, n2, n1, d1); -+ umul_ppmm(m1, m0, q0, d0); -+ -+ if (m1 > n1 || (m1 == n1 && m0 > n0)) { -+ q0--; -+ sub_ddmmss(m1, m0, m1, m0, d1, d0); -+ } -+ -+ q1 = 0; -+ -+ /* Remainder in (n1n0 - m1m0) >> bm. */ -+ if (rp != 0) { -+ sub_ddmmss(n1, n0, n1, n0, m1, m0); -+ rr.s.low = (n1 << b) | (n0 >> bm); -+ rr.s.high = n1 >> bm; -+ *rp = rr.ll; -+ } -+ } -+ } -+ } -+ -+ ww.s.low = q0, ww.s.high = q1; -+ return ww.ll; -+} -+ -+UDWtype __umoddi3(UDWtype u, UDWtype v) -+{ -+ UDWtype w; -+ -+ (void)__udivmoddi4(u, v, &w); -+ -+ return w; -+} -+ -+UDWtype __udivdi3(UDWtype n, UDWtype d) -+{ -+ return __udivmoddi4(n, d, (UDWtype *) 0); -+} -+ -+word_type __ucmpdi2(DWtype a, DWtype b) -+{ -+ const DWunion au = {.ll = a }; -+ const DWunion bu = {.ll = b }; -+ -+ if ((UWtype) au.s.high < (UWtype) bu.s.high) -+ return 0; -+ else if ((UWtype) au.s.high > (UWtype) bu.s.high) -+ return 2; -+ if ((UWtype) au.s.low < (UWtype) bu.s.low) -+ return 0; -+ else if ((UWtype) au.s.low > (UWtype) bu.s.low) -+ return 2; -+ return 1; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/lib/longlong.h linux-3.4.113/arch/nds32/lib/longlong.h ---- linux-3.4.113.orig/arch/nds32/lib/longlong.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/longlong.h 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,105 @@ -+#define __BITS4 (W_TYPE_SIZE / 4) -+#define __ll_B ((UWtype) 1 << (W_TYPE_SIZE / 2)) -+#define __ll_lowpart(t) ((UWtype) (t) & (__ll_B - 1)) -+#define __ll_highpart(t) ((UWtype) (t) >> (W_TYPE_SIZE / 2)) -+ -+#define W_TYPE_SIZE (4 * 8) -+#define UHWtype USItype -+ -+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \ -+ do { \ -+ UWtype __x; \ -+ __x = (al) - (bl); \ -+ (sh) = (ah) - (bh) - (__x > (al)); \ -+ (sl) = __x; \ -+ } while (0) -+ -+#define umul_ppmm(w1, w0, u, v) \ -+ do { \ -+ UWtype __x0, __x1, __x2, __x3; \ -+ UHWtype __ul, __vl, __uh, __vh; \ -+ \ -+ __ul = __ll_lowpart (u); \ -+ __uh = __ll_highpart (u); \ -+ __vl = __ll_lowpart (v); \ -+ __vh = __ll_highpart (v); \ -+ \ -+ __x0 = (UWtype) __ul * __vl; \ -+ __x1 = (UWtype) __ul * __vh; \ -+ __x2 = (UWtype) __uh * __vl; \ -+ __x3 = (UWtype) __uh * __vh; \ -+ \ -+ __x1 += __ll_highpart (__x0);/* this can't give carry */ \ -+ __x1 += __x2; /* but this indeed can */ \ -+ if (__x1 < __x2) /* did we get it? */ \ -+ __x3 += __ll_B; /* yes, add it in the proper pos. */ \ -+ \ -+ (w1) = __x3 + __ll_highpart (__x1); \ -+ (w0) = __ll_lowpart (__x1) * __ll_B + __ll_lowpart (__x0); \ -+ } while (0) -+ -+#define __umulsidi3(u, v) \ -+ ({DWunion __w; \ -+ umul_ppmm (__w.s.high, __w.s.low, u, v); \ -+ __w.ll; }) -+ -+#define __udiv_qrnnd_c(q, r, n1, n0, d) \ -+ do { \ -+ UWtype __d1, __d0, __q1, __q0; \ -+ UWtype __r1, __r0, __m; \ -+ __d1 = __ll_highpart (d); \ -+ __d0 = __ll_lowpart (d); \ -+ \ -+ __r1 = (n1) % __d1; \ -+ __q1 = (n1) / __d1; \ -+ __m = (UWtype) __q1 * __d0; \ -+ __r1 = __r1 * __ll_B | __ll_highpart (n0); \ -+ if (__r1 < __m) \ -+ { \ -+ __q1--, __r1 += (d); \ -+ if (__r1 >= (d)) /* i.e. we didn't get carry when adding to __r1 */\ -+ if (__r1 < __m) \ -+ __q1--, __r1 += (d); \ -+ } \ -+ __r1 -= __m; \ -+ \ -+ __r0 = __r1 % __d1; \ -+ __q0 = __r1 / __d1; \ -+ __m = (UWtype) __q0 * __d0; \ -+ __r0 = __r0 * __ll_B | __ll_lowpart (n0); \ -+ if (__r0 < __m) \ -+ { \ -+ __q0--, __r0 += (d); \ -+ if (__r0 >= (d)) \ -+ if (__r0 < __m) \ -+ __q0--, __r0 += (d); \ -+ } \ -+ __r0 -= __m; \ -+ \ -+ (q) = (UWtype) __q1 * __ll_B | __q0; \ -+ (r) = __r0; \ -+ } while (0) -+ -+#define UDIV_NEEDS_NORMALIZATION 1 -+#define udiv_qrnnd __udiv_qrnnd_c -+ -+#define count_leading_zeros(count, x) \ -+ do { \ -+ UWtype __xr = (x); \ -+ UWtype __a; \ -+ \ -+ if (W_TYPE_SIZE <= 32) \ -+ { \ -+ __a = __xr < ((UWtype)1<<2*__BITS4) \ -+ ? (__xr < ((UWtype)1<<__BITS4) ? 0 : __BITS4) \ -+ : (__xr < ((UWtype)1<<3*__BITS4) ? 2*__BITS4 : 3*__BITS4); \ -+ } \ -+ else \ -+ { \ -+ for (__a = W_TYPE_SIZE - 8; __a > 0; __a -= 8) \ -+ if (((__xr >> __a) & 0xff) != 0) \ -+ break; \ -+ } \ -+ \ -+ (count) = W_TYPE_SIZE - (__clz_tab[__xr >> __a] + __a); \ -+ } while (0) -diff -Nur linux-3.4.113.orig/arch/nds32/lib/Makefile linux-3.4.113/arch/nds32/lib/Makefile ---- linux-3.4.113.orig/arch/nds32/lib/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/Makefile 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,19 @@ -+# -+# linux/arch/nds32/lib/Makefile -+# -+# Copyright (C) 2006 Andes Technology Corporation -+# -+ -+lib-y := csum_partial_copy.o csum_partial.o \ -+ copy_page.o memcpy.o memmove.o \ -+ memset.o memzero.o strncpy_from_user.o \ -+ strnlen_user.o strchr.o strrchr.o \ -+ uaccess.o getuser.o \ -+ putuser.o libgcc2.o divmod.o udivmod.o udivmodsi4.o -+ -+ifdef CONFIG_FUNCTION_TRACER -+CFLAGS_REMOVE_libgcc2.o = -pg -+CFLAGS_REMOVE_divmod.o = -pg -+CFLAGS_REMOVE_udivmod.o = -pg -+CFLAGS_REMOVE_udivmodsi4.o = -pg -+endif -diff -Nur linux-3.4.113.orig/arch/nds32/lib/memcpy.S linux-3.4.113/arch/nds32/lib/memcpy.S ---- linux-3.4.113.orig/arch/nds32/lib/memcpy.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/memcpy.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,101 @@ -+/* -+ * linux/arch/nds32/lib/memcpy.S -- Memory copy function. -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2001 Hiroyuki Kondo, and Hirokazu Takata -+ * Copyright (C) 2004 Hirokazu Takata -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ */ -+ -+#include -+ -+/* -+ void *memcpy(void *dst, const void *src, int n); -+ -+ dst: $r0 -+ src: $r1 -+ n : $r2 -+ ret: $r0 - pointer to the memory area dst. -+*/ -+ -+#include -+ -+ .text -+ -+ENTRY(memcpy) -+ move $r5, $r0 -+ beq $r0, $r1, quit_memcpy -+ beqz $r2, quit_memcpy -+ srli $r3, $r2, #5 ! check if len < cache-line size 32 -+ beqz $r3, word_copy_entry -+ andi $r4, $r0, #0x3 ! check byte-align -+ beqz $r4, unalign_word_copy_entry -+ -+ addi $r4, $r4,#-4 -+ abs $r4, $r4 ! check how many un-align byte to copy -+ sub $r2, $r2, $r4 ! update $R2 -+ -+unalign_byte_copy: -+ lbi.bi $r3, [$r1], #1 -+ addi $r4, $r4, #-1 -+ sbi.bi $r3, [$r0], #1 -+ bnez $r4, unalign_byte_copy -+ beqz $r2, quit_memcpy -+ -+unalign_word_copy_entry: -+ andi $r3, $r0, 0x1f ! check cache-line unaligncount -+ beqz $r3, cache_copy -+ -+ addi $r3, $r3, #-32 -+ abs $r3, $r3 -+ sub $r2, $r2, $r3 ! update $R2 -+ -+unalign_word_copy: -+ lmw.bim $r4, [$r1], $r4 -+ addi $r3, $r3, #-4 -+ smw.bim $r4, [$r0], $r4 -+ bnez $r3, unalign_word_copy -+ beqz $r2, quit_memcpy -+ -+ addi $r3, $r2, #-32 ! to check $r2< cache_line , than go to word_copy -+ bltz $r3, word_copy_entry -+cache_copy: -+ srli $r3, $r2, #5 -+ beqz $r3, word_copy_entry -+ pushm $r6, $r13 -+3: -+ lmw.bim $r6, [$r1], $r13 -+ addi $r3, $r3, #-1 -+ smw.bim $r6, [$r0], $r13 -+ bnez $r3, 3b -+ popm $r6, $r13 -+ -+word_copy_entry: -+ andi $r2, $r2, #31 -+ -+ beqz $r2, quit_memcpy -+5: -+ srli $r3, $r2, #2 -+ beqz $r3, byte_copy -+word_copy: -+ lmw.bim $r4, [$r1], $r4 -+ addi $r3, $r3, #-1 -+ smw.bim $r4, [$r0], $r4 -+ bnez $r3, word_copy -+ andi $r2, $r2, #3 -+ beqz $r2, quit_memcpy -+byte_copy: -+ lbi.bi $r3, [$r1], #1 -+ addi $r2, $r2, #-1 -+ -+ sbi.bi $r3, [$r0], #1 -+ bnez $r2, byte_copy -+quit_memcpy: -+ move $r0, $r5 -+ ret -+ -+ .end -diff -Nur linux-3.4.113.orig/arch/nds32/lib/memmove.S linux-3.4.113/arch/nds32/lib/memmove.S ---- linux-3.4.113.orig/arch/nds32/lib/memmove.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/memmove.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,80 @@ -+/* -+ * linux/arch/nds32/lib/memmove.S -- Memory move function. -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2001 Hiroyuki Kondo, and Hirokazu Takata -+ * Copyright (C) 2004 Hirokazu Takata -+ * Copyright (C) 2006 Andes Technology Corporation -+ * -+ */ -+ -+#include -+ -+/* -+ void *memmove(void *dst, const void *src, int n); -+ -+ dst: $r0 -+ src: $r1 -+ n : $r2 -+ ret: $r0 - pointer to the memory area dst. -+*/ -+ .text -+ -+ENTRY(memmove) -+ move $r5, $r0 ! Set return value = det -+ beq $r0, $r1, exit_memcpy ! Exit when det = src -+ beqz $r2, exit_memcpy ! Exit when n = 0 -+ pushm $t0, $t1 ! Save reg -+ srli $p1, $r2, #2 ! $p1 is how many words to copy -+ -+ ! Avoid data lost when memory overlap -+ ! Copy data reversely when src < dst -+ slt $p0, $r0, $r1 ! check if $r0 < $r1 -+ beqz $p0, do_reverse ! branch if dst > src -+ -+ ! No reverse, dst < src -+ andi $r2, $r2, #3 ! How many bytes are less than a word -+ li $t0, #1 ! Determining copy direction in byte_cpy -+ beqz $p1, byte_cpy ! When n is less than a word -+ -+word_cpy: -+ lmw.bim $p0, [$r1], $p0 ! Read a word from src -+ addi $p1, $p1, #-1 ! How many words left to copy -+ smw.bim $p0, [$r0], $p0 ! Copy the word to det -+ bnez $p1, word_cpy ! If remained words > 0 -+ beqz $r2, end_memcpy ! No left bytes to copy -+ b byte_cpy -+ -+do_reverse: -+ add $r0, $r0, $r2 ! Start with the end of $r0 -+ add $r1, $r1, $r2 ! Start with the end of $r1 -+ andi $r2, $r2, #3 ! How many bytes are less than a word -+ li $t0, #-1 ! Determining copy direction in byte_cpy -+ beqz $p1, reverse_byte_cpy ! When n is less than a word -+ -+reverse_word_cpy: -+ lmw.adm $p0, [$r1], $p0 ! Read a word from src -+ addi $p1, $p1, #-1 ! How many words left to copy -+ smw.adm $p0, [$r0], $p0 ! Copy the word to det -+ bnez $p1, reverse_word_cpy ! If remained words > 0 -+ beqz $r2, end_memcpy ! No left bytes to copy -+ -+reverse_byte_cpy: -+ addi $r0, $r0, #-1 -+ addi $r1, $r1, #-1 -+byte_cpy: ! Less than 4 bytes to copy now -+ lb.bi $p0, [$r1], $t0 ! Read a byte from src -+ addi $r2, $r2, #-1 ! How many bytes left to copy -+ sb.bi $p0, [$r0], $t0 ! copy the byte to det -+ bnez $r2, byte_cpy ! If remained bytes > 0 -+ -+end_memcpy: -+ popm $t0, $t1 -+exit_memcpy: -+ move $r0, $r5 -+ ret -+ -+ .end -diff -Nur linux-3.4.113.orig/arch/nds32/lib/memset.S linux-3.4.113/arch/nds32/lib/memset.S ---- linux-3.4.113.orig/arch/nds32/lib/memset.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/memset.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,51 @@ -+ -+/* -+ * linux/arch/nds32/lib/memset.S -- memset function. -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2001,2002 Hiroyuki Kondo, and Hirokazu Takata -+ * Copyright (C) 2004 Hirokazu Takata -+ * Copyright (C) 2006 Andes Technology Corporation -+ * -+ */ -+#include -+#include -+ -+/* -+ void *memset(void *dst, int val, int len); -+ -+ dst: $r0 -+ val: $r1 -+ len: $r2 -+ ret: $r0 - pointer to the memory area dst. -+*/ -+ .text -+ENTRY(memset) -+ move $r5, $r0 ! Return value -+ beqz $r2, end_memset ! Exit when len = 0 -+ srli $p1, $r2, 2 ! $p1 is how many words to copy -+ andi $r2, $r2, 3 ! How many bytes are less than a word -+ beqz $p1, byte_set ! When n is less than a word -+ -+ ! set $r1 from ??????ab to abababab -+ andi $r1, $r1, #0x00ff ! $r1 = 000000ab -+ slli $p0, $r1, #8 ! $p0 = 0000ab00 -+ or $r1, $r1, $p0 ! $r1 = 0000abab -+ slli $p0, $r1, #16 ! $p0 = abab0000 -+ or $r1, $r1, $p0 ! $r1 = abababab -+word_set: -+ addi $p1, $p1, #-1 ! How many words left to copy -+ smw.bim $r1, [$r0], $r1 ! Copy the word to det -+ bnez $p1, word_set ! Still words to set, continue looping -+ beqz $r2, end_memset ! No left byte to set -+byte_set: ! Less than 4 bytes left to set -+ addi $r2, $r2, #-1 ! Decrease len by 1 -+ sbi.bi $r1, [$r0], #1 ! Set data of the next byte to $r1 -+ bnez $r2, byte_set ! Still bytes left to set -+end_memset: -+ move $r0, $r5 -+ ret -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/memzero.S linux-3.4.113/arch/nds32/lib/memzero.S ---- linux-3.4.113.orig/arch/nds32/lib/memzero.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/memzero.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * linux/arch/nds32/lib/memzero.S -+ * -+ * Copyright (C) 1995-2000 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+ -+ .text -+/* -+ * void *__memzero(void *dst, int len); -+ * -+ * dst: $r0 -+ * len: $r1 -+ * ret: $r0 - pointer to the memory area dst. -+ * -+ * Call memset(dst, 0, len) to perform memzero. -+ * Currently no optimization because only being referenced in 31 files -+ * (For comparison, memset being referenced in 2527 files) -+ */ -+ENTRY(__memzero) -+ beqz $r1, 1f -+ push $lp -+ move $r2, $r1 -+ move $r1, #0 -+ push $r0 -+ bal memset -+ pop $r0 -+ pop $lp -+1: -+ ret -diff -Nur linux-3.4.113.orig/arch/nds32/lib/putuser.S linux-3.4.113/arch/nds32/lib/putuser.S ---- linux-3.4.113.orig/arch/nds32/lib/putuser.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/putuser.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,68 @@ -+/* -+ * linux/arch/nds32/lib/putuser.S -+ * -+ * Copyright (C) 2001 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Idea from x86 version, (C) Copyright 1998 Linus Torvalds -+ * -+ * These functions have a non-standard call interface to make -+ * them more efficient, especially as they return an error -+ * value in addition to the "real" return value. -+ * -+ * __put_user_X -+ * -+ * Inputs: $r0 contains the address -+ * $r2, $r3 contains the value -+ * Outputs: $r0 is the error code -+ * lr corrupted -+ * -+ * No other registers must be altered. (see include/asm-arm/uaccess.h -+ * for specific ASM register usage). -+ * -+ * Note that ADDR_LIMIT is either 0 or 0xc0000000 -+ * Note also that it is intended that __put_user_bad is not global. -+ */ -+#include -+#include -+#include -+#include -+ -+ .text -+ -+ENTRY(__put_user_1) -+1: sb $r2, [$r0] -+ move $r0, #0 -+ ret -+ -+ENTRY(__put_user_2) -+2: shi $r2, [$r0] ! Store input halfword -+ move $r0, #0 -+ ret -+ -+ENTRY(__put_user_4) -+3: sw $r2, [$r0] -+ move $r0, #0 -+ ret -+ -+ENTRY(__put_user_8) -+5: swi.bi $r2, [$r0], #4 -+6: sw $r3, [$r0] -+ move $r0, #0 -+ ret -+ -+__put_user_bad: -+ move $r0, #-EFAULT -+ ret -+ -+.section __ex_table, "a" -+ .long 1b, __put_user_bad -+ .long 2b, __put_user_bad -+ .long 3b, __put_user_bad -+ .long 5b, __put_user_bad -+ .long 6b, __put_user_bad -+.previous -diff -Nur linux-3.4.113.orig/arch/nds32/lib/strchr.S linux-3.4.113/arch/nds32/lib/strchr.S ---- linux-3.4.113.orig/arch/nds32/lib/strchr.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/strchr.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,37 @@ -+/* -+ * linux/arch/nds32/lib/strchr.S -+ * -+ * Copyright (C) 1995-2000 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * ASM optimised string functions -+ */ -+#include -+#include -+ -+/* -+ * Prototype: char *strrchr(const char *s, int c); -+ * Purpose : Returns a pointer to the first occurrence of the character c -+ * in the string s. Here "character" means "byte" - these functions -+ * do not work with wide or multi-byte characters. -+ */ -+ -+ .text -+ -+ENTRY(strchr) -+ move $r5, $r0 ! Setup return value -+ andi $r1, $r1, #0xff ! Wipe out useless bits -+loop: -+ lbi.bi $p0, [$r5], #1 ! Load the next byte -+ beqz $p0, exit ! Reach EOS (NULL), return NULL -+ bne $p0, $r1, loop ! Continue if != c -+ addi $r5, $r5, #-1 ! Found -+exit: -+ cmovz $r5, $p0, $p0 ! Return NULL if EOS (NULL) -+ move $r0, $r5 -+ ret -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/strncpy_from_user.S linux-3.4.113/arch/nds32/lib/strncpy_from_user.S ---- linux-3.4.113.orig/arch/nds32/lib/strncpy_from_user.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/strncpy_from_user.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,45 @@ -+/* -+ * linux/arch/nds32/lib/strncpy_from_user.S -+ * -+ * Copyright (C) 1995-2000 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+ -+ -+/* -+ * Copy a string from user space to kernel space. -+ * $r0 = dst, $r1 = src, $r2 = n (byte length) -+ * returns the number of characters copied (strlen of copied string), -+ * -EFAULT on exception, or "len" if we fill the whole buffer -+ */ -+ -+ .text -+ .align 4 -+ENTRY(__arch_strncpy_from_user) -+ move $p1, $r1 ! Record the start src addr -+loop: -+ addi $r2, $r2, #-1 ! Decrease n by 1 -+ bltz $r2, exit ! Exit if n < 0 -+USER( lbi.bi, $p0, [$r1], #1) ! Load the byte from src -+ sbi.bi $p0, [$r0], #1 ! Store the byte to dst -+ bnez $p0, loop ! Continue looping if terminator is not reached -+ addi $r1, $r1, #-1 ! Don't count the terminator -+exit: -+ sub $r0, $r1, $p1 ! Get copied count -+ ret -+ -+ .section .fixup,"ax" -+ .align 0 -+9001: xor $p0, $p0, $p0 -+ sb $p0, [$r0] ! Zero the buffer -+ move $r0, -EFAULT ! Return -EFAULT -+ ret -+ .previous -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/strnlen_user.S linux-3.4.113/arch/nds32/lib/strnlen_user.S ---- linux-3.4.113.orig/arch/nds32/lib/strnlen_user.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/strnlen_user.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,43 @@ -+/* -+ * linux/arch/nds32/lib/strnlen_user.S -+ * -+ * Copyright (C) 1995-2000 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+ -+ .text -+ -+/* Prototype: unsigned long ___arch_strnlen_user(const char *str, long n) -+ * Purpose : get length of a string in user memory -+ * Params : str - address of string in user memory -+ * Returns : length of string *including terminator* -+ * or zero on exception, or n + 1 if too long -+ */ -+ .align 4 -+ENTRY(__arch_strnlen_user) -+ move $p0, $r0 ! Record the start addr -+ ! beqz $r0, exit ! Exit when Null address -+ beqz $r1, exit ! Exit when n = 0 -+loop: -+USER( lbi.bi, $p1, [$r0], #1) ! Load the next byte -+ beqz $p1, exit ! Exit when terminator is reached -+ addi $r1, $r1, #-1 ! Decrease n by 1 -+ bnez $r1, loop ! Continue looping if n != 0 -+ addi $r0, $r0, #1 ! Return n+1 if too long -+exit: -+ sub $r0, $r0, $p0 ! Get the counted length -+ ret -+ -+ .section .fixup,"ax" -+ .align 0 -+9001: move $r0, #0 ! Return 0 on exception -+ ret -+ .previous -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/strrchr.S linux-3.4.113/arch/nds32/lib/strrchr.S ---- linux-3.4.113.orig/arch/nds32/lib/strrchr.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/strrchr.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,37 @@ -+/* -+ * linux/arch/nds32/lib/strrchr.S -+ * -+ * Copyright (C) 1995-2000 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * ASM optimised string functions -+ */ -+#include -+#include -+ -+ .text -+/* -+ * Prototype: char *strrchr(const char *s, int c); -+ * Purpose : Returns a pointer to the last occurrence of the character c -+ * in the string s. Here "character" means "byte" - these functions -+ * do not work with wide or multi-byte characters. -+ */ -+ .align 4 -+ENTRY(strrchr) -+ move $r5, #0 -+ beqz $r0, exit -+ andi $r1, $r1, #0xff ! Wipe out useless bits -+loop: -+ lbi $p0, [$r0] ! Load the next byte -+ xor $p1, $p0, $r1 ! Test if the byte == c -+ cmovz $r5, $r0, $p1 ! Save the current position -+ addi $r0, $r0, #1 ! Move on to the next byte -+ bnez $p0, loop ! Continue if not NULL (EOS) -+exit: -+ move $r0, $r5 -+ ret -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/uaccess.S linux-3.4.113/arch/nds32/lib/uaccess.S ---- linux-3.4.113.orig/arch/nds32/lib/uaccess.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/uaccess.S 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,159 @@ -+/* -+ * linux/arch/nds32/lib/uaccess.S -+ * -+ * Copyright (C) 1995, 1996,1997,1998 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Routines to block copy data to/from user memory -+ * These are highly optimised both for the 4k page size -+ * and for various alignments. -+ */ -+#include -+#include -+#include -+ -+ .text -+ -+//#define PAGE_SHIFT 12 -+ -+/* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) -+ * Purpose : copy a block to user memory from kernel memory -+ * Params : to - user memory -+ * : from - kernel memory -+ * : n - number of bytes to copy -+ * Returns : Number of bytes NOT copied. -+ */ -+ -+ENTRY(__arch_copy_to_user) -+ push $r0 -+ push $r2 -+ beqz $r2, ctu_exit -+ srli $p0, $r2, #2 ! $p0 = number of word to clear -+ andi $r2, $r2, #3 ! Bytes less than a word to copy -+ beqz $p0, byte_ctu ! Only less than a word to copy -+word_ctu: -+ lmw.bim $p1, [$r1], $p1 ! Load the next word -+USER( smw.bim,$p1, [$r0], $p1) ! Store the next word -+ addi $p0, $p0, #-1 ! Decrease word count -+ bnez $p0, word_ctu ! Continue looping to copy all words -+ beqz $r2, ctu_exit ! No left bytes to copy -+byte_ctu: -+ lbi.bi $p1, [$r1], #1 ! Load the next byte -+USER( sbi.bi, $p1, [$r0], #1) ! Store the next byte -+ addi $r2, $r2, #-1 ! Decrease byte count -+ bnez $r2, byte_ctu ! Continue looping to clear all left bytes -+ctu_exit: -+ move $r0, $r2 ! Set return value -+ pop $r2 -+ pop $r2 ! Pop saved $r0 to $r2 to not corrupt return value -+ ret -+ -+ .section .fixup,"ax" -+ .align 0 -+9001: -+ pop $p1 ! Original $r2, n -+ pop $p0 ! Original $r0, void *to -+ sub $r1, $r0, $p0 ! Bytes copied -+ sub $r2, $p1, $r1 ! Bytes left to copy -+ push $lp -+ move $r0, $p0 -+ bal __memzero ! Clean up the memory -+ pop $lp -+ move $r0, $r2 -+ ret -+ -+ .previous -+ -+/* Prototype: unsigned long __arch_copy_from_user(void *to,const void *from,unsigned long n); -+ * Purpose : copy a block from user memory to kernel memory -+ * Params : to - kernel memory -+ * : from - user memory -+ * : n - number of bytes to copy -+ * Returns : Number of bytes NOT copied. -+ */ -+ -+ -+ENTRY(__arch_copy_from_user) -+ push $r1 -+ push $r2 -+ beqz $r2, cfu_exit -+ srli $p0, $r2, #2 ! $p0 = number of word to clear -+ andi $r2, $r2, #3 ! Bytes less than a word to copy -+ beqz $p0, byte_cfu ! Only less than a word to copy -+word_cfu: -+USER( lmw.bim,$p1, [$r1], $p1) ! Load the next word -+ smw.bim $p1, [$r0], $p1 ! Store the next word -+ addi $p0, $p0, #-1 ! Decrease word count -+ bnez $p0, word_cfu ! Continue looping to copy all words -+ beqz $r2, cfu_exit ! No left bytes to copy -+byte_cfu: -+USER( lbi.bi, $p1, [$r1], #1) ! Load the next byte -+ sbi.bi $p1, [$r0], #1 ! Store the next byte -+ addi $r2, $r2, #-1 ! Decrease byte count -+ bnez $r2, byte_cfu ! Continue looping to clear all left bytes -+cfu_exit: -+ move $r0, $r2 ! Set return value -+ pop $r2 -+ pop $r1 -+ ret -+ -+ .section .fixup,"ax" -+ .align 0 -+ /* -+ * We took an exception. $r0 contains a pointer to -+ * the byte not copied. -+ */ -+9001: -+ pop $p1 ! Original $r2, n -+ pop $p0 ! Original $r0, void *to -+ sub $r1, $r1, $p0 ! Bytes copied -+ sub $r2, $p1, $r1 ! Bytes left to copy -+ push $lp -+ bal __memzero ! Clean up the memory -+ pop $lp -+ move $r0, $r2 -+ ret -+ .previous -+ -+/* Prototype: int __arch_clear_user(void *addr, size_t sz) -+ * Purpose : clear some user memory -+ * Params : addr - user memory address to clear -+ * : sz - number of bytes to clear -+ * Returns : number of bytes NOT cleared -+ */ -+ .align 5 -+ENTRY(__arch_clear_user) -+ pushm $r0, $r1 -+ beqz $r1, clear_exit -+ xor $p1, $p1, $p1 ! Use $p1=0 to clear mem -+ srli $p0, $r1, #2 ! $p0 = number of word to clear -+ andi $r1, $r1, #3 ! Bytes less than a word to copy -+ beqz $p0, byte_clear ! Only less than a word to clear -+word_clear: -+USER( smw.bim,$p1, [$r0], $p1) ! Clear the word -+ addi $p0, $p0, #-1 ! Decrease word count -+ bnez $p0, word_clear ! Continue looping to clear all words -+ beqz $r1, clear_exit ! No left bytes to copy -+byte_clear: -+USER( sbi.bi, $p1, [$r0], #1) ! Clear the byte -+ addi $r1, $r1, #-1 ! Decrease byte count -+ bnez $r1, byte_clear ! Continue looping to clear all left bytes -+clear_exit: -+ move $r0, $r1 ! Set return value -+ pop $r1 -+ pop $r1 ! Pop saved $r0 to $r1 to not corrupt return value -+ ret -+ -+ .section .fixup,"ax" -+ .align 0 -+9001: -+ popm $p0, $p1 ! $p0 = original $r0, *addr, $p1 = original $r1, n -+ sub $p0, $r0, $p0 ! Bytes copied -+ sub $r0, $p1, $p0 ! Bytes left to copy -+ ret -+ .previous -+ -diff -Nur linux-3.4.113.orig/arch/nds32/lib/udivmod.c linux-3.4.113/arch/nds32/lib/udivmod.c ---- linux-3.4.113.orig/arch/nds32/lib/udivmod.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/udivmod.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,12 @@ -+extern unsigned long udivmodsi4(unsigned long num, unsigned long den, -+ int modwanted); -+ -+long __udivsi3(long a, long b) -+{ -+ return udivmodsi4(a, b, 0); -+} -+ -+long __umodsi3(long a, long b) -+{ -+ return udivmodsi4(a, b, 1); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/lib/udivmodsi4.c linux-3.4.113/arch/nds32/lib/udivmodsi4.c ---- linux-3.4.113.orig/arch/nds32/lib/udivmodsi4.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/lib/udivmodsi4.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,21 @@ -+unsigned long udivmodsi4(unsigned long num, unsigned long den, int modwanted) -+{ -+ unsigned long bit = 1; -+ unsigned long res = 0; -+ -+ while (den < num && bit && !(den & (1L << 31))) { -+ den <<= 1; -+ bit <<= 1; -+ } -+ while (bit) { -+ if (num >= den) { -+ num -= den; -+ res |= bit; -+ } -+ bit >>= 1; -+ den >>= 1; -+ } -+ if (modwanted) -+ return num; -+ return res; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/Makefile linux-3.4.113/arch/nds32/Makefile ---- linux-3.4.113.orig/arch/nds32/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/Makefile 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,100 @@ -+# -+# arch/nds32/Makefile -+# -+# This file is subject to the terms and conditions of the GNU General Public -+# License. See the file "COPYING" in the main directory of this archive -+# for more details. -+# -+# Copyright (C) 1995-2001 by Russell King -+ -+LDFLAGS_vmlinux :=-nostdlib --no-undefined -X -+OBJCOPYFLAGS :=-O binary -R .note -R .note.gnu.build-id -R .comment -S -+GZFLAGS :=-9 -+KBUILD_CFLAGS +=-pipe -mno-sched-prolog-epilog -+ -+# Do not use arch/nds32/defconfig - it's always outdated. -+# Select a platform tht is kept up-to-date -+KBUILD_DEFCONFIG := orca_defconfig -+ -+ifeq ($(CONFIG_FRAME_POINTER),y) -+KBUILD_CFLAGS +=-fno-omit-frame-pointer -+endif -+ -+comma = , -+ -+# This selects which instruction set is used. -+# Note that GCC does not numerically define an architecture version -+# macro, but instead defines a whole series of macros which makes -+# testing for a specific architecture or later rather impossible. -+arch-y +=-D__nds32__ -+gcc_ver :=$(shell $(CC) -E -dM -xc /dev/null | grep __VERSION__ | sed 's/\#define __VERSION__ //') -+ifeq ($(shell expr `echo $(gcc_ver)` \>= 4.9.2 ), 1) -+arch-y += \ -+ $(shell $(CC) -E -dM -xc /dev/null | \ -+ grep -o -m1 NDS32_EXT_FPU_SP | \ -+ sed -e 's/NDS32_EXT_FPU_SP/-mno-ext-fpu-sp -mfloat-abi=soft/') \ -+ $(shell $(CC) -E -dM -xc /dev/null | \ -+ grep -o -m1 NDS32_EXT_FPU_DP | \ -+ sed -e 's/NDS32_EXT_FPU_DP/-mno-ext-fpu-dp -mfloat-abi=soft/') -+tune-y =-D__OPTIMIZE__ -mcmodel=large -D__ARCH_WANT_SYS_WAITPID -+else -+$(shell echo $(__VERSION__)) -+arch-y += $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_SP | \ -+ sed -e 's/NDS32_EXT_FPU_SP/-mno-ext-fpu-sp/') \ -+ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_EXT_FPU_DP | \ -+ sed -e 's/NDS32_EXT_FPU_DP/-mno-ext-fpu-dp/') \ -+ $(shell $(CC) -E -dM -xc /dev/null | grep -o -m1 NDS32_ABI | \ -+ sed -e 's/NDS32_ABI/-mabi=2/') -+tune-y =-D__OPTIMIZE__ -G0 -D__ARCH_WANT_SYS_WAITPID -D_GCC444 -+endif -+ -+# This is a workaround for FUNCTION_TRACER because v3push will push $fp, $gp and $lp. -+ifdef CONFIG_FUNCTION_TRACER -+arch-y += -mno-v3push -+endif -+# This selects how we optimise for the processor. -+# Need -Unds32 for gcc < 3.x -+CHECKFLAGS += -D__nds32__ -+ -+KBUILD_CFLAGS +=$(CFLAGS_ABI) $(arch-y) $(tune-y) -Unds32 -DSTRICT_MM_TYPECHECKS # for c-style checking for page.h -+KBUILD_AFLAGS +=$(AFLAGS_ABI) $(arch-y) $(tune-y) -+ -+#Default value -+head-y := arch/nds32/kernel/head.o arch/nds32/kernel/init_task.o -+textaddr-y := 0xC000C000 -+ -+TEXTADDR := $(textaddr-y) -+ -+export TEXTADDR DATAADDR GZFLAGS -+ -+ -+# If we have a machine-specific directory, then include it in the build. -+core-y += arch/nds32/kernel/ arch/nds32/mm/ -+core-y += arch/nds32/platforms/ -+core-$(CONFIG_FPU) += arch/nds32/math-emu/ -+ -+drivers-$(CONFIG_OPROFILE) += arch/nds32/oprofile/ -+ -+libs-y += arch/nds32/lib/ -+ -+boot := arch/nds32/boot -+ -+.PHONY: FORCE -+ -+Image: vmlinux -+ $(Q)$(MAKE) $(build)=$(boot) $(boot)/$@ -+ -+CLEAN_FILES += include/asm-nds32/constants.h* -+ -+# We use MRPROPER_FILES and CLEAN_FILES now -+archclean: -+ $(Q)$(MAKE) $(clean)=$(boot) -+ -+.PHONY: arch/nds32/kernel/asm-offsets.s -+arch/nds32/kernel/asm-offsets.s: arch/nds32/kernel/asm-offsets.c -+ $(Q)$(MAKE) $(build)=$(build-dir) $(target-dir)$(notdir $@) -+ -+ -+define archhelp -+ echo ' Image - kernel image (arch/$(ARCH)/boot/Image)' -+endef -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_add.c linux-3.4.113/arch/nds32/math-emu/dp_add.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_add.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,179 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ * -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y) -+{ -+ COMPXDP; -+ COMPYDP; -+ -+ EXPLODEXDP; -+ EXPLODEYDP; -+ -+ CLEARCX; -+ -+ FLUSHXDP; -+ FLUSHYDP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "add", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ if (xs == ys) -+ return x; -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_xcpt(ieee754dp_indef(), "add", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ return x; -+ -+ /* Zero handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ if (xs == ys) -+ return x; -+ else -+ return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ return x; -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ DPDNORMX; -+ -+ /* FALL THROUGH */ -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ DPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ DPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ assert(xm & DP_HIDDEN_BIT); -+ assert(ym & DP_HIDDEN_BIT); -+ -+ /* provide guard,round and stick bit space */ -+ xm <<= 3; -+ ym <<= 3; -+ -+ if (xe > ye) { -+ /* have to shift y fraction right to align -+ */ -+ int s = xe - ye; -+ ym = XDPSRS(ym, s); -+ ye += s; -+ } else if (ye > xe) { -+ /* have to shift x fraction right to align -+ */ -+ int s = ye - xe; -+ xm = XDPSRS(xm, s); -+ xe += s; -+ } -+ assert(xe == ye); -+ assert(xe <= DP_EMAX); -+ -+ if (xs == ys) { -+ /* generate 28 bit result of adding two 27 bit numbers -+ * leaving result in xm,xs,xe -+ */ -+ xm = xm + ym; -+ xe = xe; -+ xs = xs; -+ -+ if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */ -+ xm = XDPSRS1(xm); -+ xe++; -+ } -+ } else { -+ if (xm >= ym) { -+ xm = xm - ym; -+ xe = xe; -+ xs = xs; -+ } else { -+ xm = ym - xm; -+ xe = xe; -+ xs = ys; -+ } -+ if (xm == 0) -+ return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD); -+ -+ /* normalize to rounding precision */ -+ while ((xm >> (DP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ -+ } -+ DPNORMRET2(xs, xe, xm, "add", x, y); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_cmp.c linux-3.4.113/arch/nds32/math-emu/dp_cmp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_cmp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_cmp.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,66 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cmp, int sig) -+{ -+ COMPXDP; -+ COMPYDP; -+ -+ EXPLODEXDP; -+ EXPLODEYDP; -+ FLUSHXDP; -+ FLUSHYDP; -+ CLEARCX; /* Even clear inexact flag here */ -+ -+ if (ieee754dp_isnan(x) || ieee754dp_isnan(y)) { -+ if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN) -+ SETCX(IEEE754_INVALID_OPERATION); -+ if (cmp & IEEE754_CUN) -+ return 1; -+ if (cmp & (IEEE754_CLT | IEEE754_CGT)) { -+ if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) -+ return ieee754si_xcpt(0, "fcmpf", x); -+ } -+ return 0; -+ } else { -+ s64 vx = x.bits; -+ s64 vy = y.bits; -+ -+ if (vx < 0) -+ vx = -vx ^ DP_SIGN_BIT; -+ if (vy < 0) -+ vy = -vy ^ DP_SIGN_BIT; -+ -+ if (vx < vy) -+ return (cmp & IEEE754_CLT) != 0; -+ else if (vx == vy) -+ return (cmp & IEEE754_CEQ) != 0; -+ else -+ return (cmp & IEEE754_CGT) != 0; -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_div.c linux-3.4.113/arch/nds32/math-emu/dp_div.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_div.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_div.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,155 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y) -+{ -+ COMPXDP; -+ COMPYDP; -+ -+ EXPLODEXDP; -+ EXPLODEYDP; -+ -+ CLEARCX; -+ -+ FLUSHXDP; -+ FLUSHYDP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ return ieee754dp_zero(xs ^ ys); -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ return ieee754dp_inf(xs ^ ys); -+ -+ /* Zero handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_xcpt(ieee754dp_indef(), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ SETCX(IEEE754_ZERO_DIVIDE); -+ return ieee754dp_xcpt(ieee754dp_inf(xs ^ ys), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ return ieee754dp_zero(xs == ys ? 0 : 1); -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ DPDNORMX; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ DPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ DPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ assert(xm & DP_HIDDEN_BIT); -+ assert(ym & DP_HIDDEN_BIT); -+ -+ /* provide rounding space */ -+ xm <<= 3; -+ ym <<= 3; -+ -+ { -+ /* now the dirty work */ -+ -+ u64 rm = 0; -+ int re = xe - ye; -+ u64 bm; -+ -+ for (bm = DP_MBIT(DP_MBITS + 2); bm; bm >>= 1) { -+ if (xm >= ym) { -+ xm -= ym; -+ rm |= bm; -+ if (xm == 0) -+ break; -+ } -+ xm <<= 1; -+ } -+ rm <<= 1; -+ if (xm) -+ rm |= 1; /* have remainder, set sticky */ -+ -+ assert(rm); -+ -+ /* normalise rm to rounding precision ? -+ */ -+ while ((rm >> (DP_MBITS + 3)) == 0) { -+ rm <<= 1; -+ re--; -+ } -+ -+ DPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_fint.c linux-3.4.113/arch/nds32/math-emu/dp_fint.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_fint.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_fint.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,79 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_fint(int x) -+{ -+ u64 xm; -+ int xe; -+ int xs; -+ -+ CLEARCX; -+ -+ if (x == 0) -+ return ieee754dp_zero(0); -+ if (x == 1 || x == -1) -+ return ieee754dp_one(x < 0); -+ if (x == 10 || x == -10) -+ return ieee754dp_ten(x < 0); -+ -+ xs = (x < 0); -+ if (xs) { -+ if (x == (1 << 31)) -+ xm = ((unsigned)1 << 31); /* max neg can't be safely negated */ -+ else -+ xm = -x; -+ } else { -+ xm = x; -+ } -+ -+#if 1 -+ /* normalize - result can never be inexact or overflow */ -+ xe = DP_MBITS; -+ while ((xm >> DP_MBITS) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -+#else -+ /* normalize */ -+ xe = DP_MBITS + 3; -+ while ((xm >> (DP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ DPNORMRET1(xs, xe, xm, "fint", x); -+#endif -+} -+ -+ieee754dp ieee754dp_funs(unsigned int u) -+{ -+ if ((int)u < 0) -+ return ieee754dp_add(ieee754dp_1e31(), -+ ieee754dp_fint(u & ~(1 << 31))); -+ return ieee754dp_fint(u); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_flong.c linux-3.4.113/arch/nds32/math-emu/dp_flong.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_flong.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_flong.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,77 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_flong(s64 x) -+{ -+ u64 xm; -+ int xe; -+ int xs; -+ -+ CLEARCX; -+ -+ if (x == 0) -+ return ieee754dp_zero(0); -+ if (x == 1 || x == -1) -+ return ieee754dp_one(x < 0); -+ if (x == 10 || x == -10) -+ return ieee754dp_ten(x < 0); -+ -+ xs = (x < 0); -+ if (xs) { -+ if (x == (1ULL << 63)) -+ xm = (1ULL << 63); /* max neg can't be safely negated */ -+ else -+ xm = -x; -+ } else { -+ xm = x; -+ } -+ -+ /* normalize */ -+ xe = DP_MBITS + 3; -+ if (xm >> (DP_MBITS + 1 + 3)) { -+ /* shunt out overflow bits */ -+ while (xm >> (DP_MBITS + 1 + 3)) { -+ XDPSRSX1(); -+ } -+ } else { -+ /* normalize in grs extended double precision */ -+ while ((xm >> (DP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ } -+ DPNORMRET1(xs, xe, xm, "dp_flong", x); -+} -+ -+ieee754dp ieee754dp_fulong(u64 u) -+{ -+ if ((s64) u < 0) -+ return ieee754dp_add(ieee754dp_1e63(), -+ ieee754dp_flong(u & ~(1ULL << 63))); -+ return ieee754dp_flong(u); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_frexp.c linux-3.4.113/arch/nds32/math-emu/dp_frexp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_frexp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_frexp.c 2016-12-01 20:59:24.360613059 +0100 -@@ -0,0 +1,52 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+/* close to ieeep754dp_logb -+*/ -+ieee754dp ieee754dp_frexp(ieee754dp x, int *eptr) -+{ -+ COMPXDP; -+ CLEARCX; -+ EXPLODEXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ case IEEE754_CLASS_ZERO: -+ *eptr = 0; -+ return x; -+ case IEEE754_CLASS_DNORM: -+ DPDNORMX; -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ *eptr = xe + 1; -+ return builddp(xs, -1 + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_fsp.c linux-3.4.113/arch/nds32/math-emu/dp_fsp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_fsp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_fsp.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,71 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_fsp(ieee754sp x) -+{ -+ COMPXSP; -+ -+ EXPLODEXSP; -+ -+ CLEARCX; -+ -+ FLUSHXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "fsp"); -+ case IEEE754_CLASS_QNAN: -+ return ieee754dp_nanxcpt(builddp(xs, -+ DP_EMAX + 1 + DP_EBIAS, -+ ((u64) xm -+ << (DP_MBITS - -+ SP_MBITS))), "fsp", x); -+ case IEEE754_CLASS_INF: -+ return ieee754dp_inf(xs); -+ case IEEE754_CLASS_ZERO: -+ return ieee754dp_zero(xs); -+ case IEEE754_CLASS_DNORM: -+ /* normalize */ -+ while ((xm >> SP_MBITS) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ -+ /* CANT possibly overflow,underflow, or need rounding -+ */ -+ -+ /* drop the hidden bit */ -+ xm &= ~SP_HIDDEN_BIT; -+ -+ return builddp(xs, xe + DP_EBIAS, (u64) xm << (DP_MBITS - SP_MBITS)); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_logb.c linux-3.4.113/arch/nds32/math-emu/dp_logb.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_logb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_logb.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,53 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_logb(ieee754dp x) -+{ -+ COMPXDP; -+ -+ CLEARCX; -+ -+ EXPLODEXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ return ieee754dp_nanxcpt(x, "logb", x); -+ case IEEE754_CLASS_QNAN: -+ return x; -+ case IEEE754_CLASS_INF: -+ return ieee754dp_inf(0); -+ case IEEE754_CLASS_ZERO: -+ return ieee754dp_inf(1); -+ case IEEE754_CLASS_DNORM: -+ DPDNORMX; -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ return ieee754dp_fint(xe); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_modf.c linux-3.4.113/arch/nds32/math-emu/dp_modf.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_modf.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_modf.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,79 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+/* modf function is always exact for a finite number -+*/ -+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip) -+{ -+ COMPXDP; -+ -+ CLEARCX; -+ -+ EXPLODEXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ case IEEE754_CLASS_ZERO: -+ *ip = x; -+ return x; -+ case IEEE754_CLASS_DNORM: -+ /* far to small */ -+ *ip = ieee754dp_zero(xs); -+ return x; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ if (xe < 0) { -+ *ip = ieee754dp_zero(xs); -+ return x; -+ } -+ if (xe >= DP_MBITS) { -+ *ip = x; -+ return ieee754dp_zero(xs); -+ } -+ /* generate ipart mantissa by clearing bottom bits -+ */ -+ *ip = builddp(xs, xe + DP_EBIAS, -+ ((xm >> (DP_MBITS - xe)) << (DP_MBITS - xe)) & -+ ~DP_HIDDEN_BIT); -+ -+ /* generate fpart mantissa by clearing top bits -+ * and normalizing (must be able to normalize) -+ */ -+ xm = (xm << (64 - (DP_MBITS - xe))) >> (64 - (DP_MBITS - xe)); -+ if (xm == 0) -+ return ieee754dp_zero(xs); -+ -+ while ((xm >> DP_MBITS) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ return builddp(xs, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_mul.c linux-3.4.113/arch/nds32/math-emu/dp_mul.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_mul.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_mul.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,170 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y) -+{ -+ COMPXDP; -+ COMPYDP; -+ -+ EXPLODEXDP; -+ EXPLODEYDP; -+ -+ CLEARCX; -+ -+ FLUSHXDP; -+ FLUSHYDP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "mul", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_xcpt(ieee754dp_indef(), "mul", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ return ieee754dp_inf(xs ^ ys); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ return ieee754dp_zero(xs ^ ys); -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ DPDNORMX; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ DPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ DPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ /* rm = xm * ym, re = xe+ye basicly */ -+ assert(xm & DP_HIDDEN_BIT); -+ assert(ym & DP_HIDDEN_BIT); -+ { -+ int re = xe + ye; -+ int rs = xs ^ ys; -+ u64 rm; -+ -+ /* shunt to top of word */ -+ xm <<= 64 - (DP_MBITS + 1); -+ ym <<= 64 - (DP_MBITS + 1); -+ -+ /* multiply 32bits xm,ym to give high 32bits rm with stickness -+ */ -+ -+ /* 32 * 32 => 64 */ -+#define DPXMULT(x, y) ((u64)(x) * (u64)y) -+ -+ { -+ unsigned lxm = xm; -+ unsigned hxm = xm >> 32; -+ unsigned lym = ym; -+ unsigned hym = ym >> 32; -+ u64 lrm; -+ u64 hrm; -+ -+ lrm = DPXMULT(lxm, lym); -+ hrm = DPXMULT(hxm, hym); -+ -+ { -+ u64 t = DPXMULT(lxm, hym); -+ { -+ u64 at = lrm + (t << 32); -+ hrm += at < lrm; -+ lrm = at; -+ } -+ hrm = hrm + (t >> 32); -+ } -+ -+ { -+ u64 t = DPXMULT(hxm, lym); -+ { -+ u64 at = lrm + (t << 32); -+ hrm += at < lrm; -+ lrm = at; -+ } -+ hrm = hrm + (t >> 32); -+ } -+ rm = hrm | (lrm != 0); -+ } -+ -+ /* -+ * sticky shift down to normal rounding precision -+ */ -+ if ((s64) rm < 0) { -+ rm = (rm >> (64 - (DP_MBITS + 1 + 3))) | -+ ((rm << (DP_MBITS + 1 + 3)) != 0); -+ re++; -+ } else { -+ rm = (rm >> (64 - (DP_MBITS + 1 + 3 + 1))) | -+ ((rm << (DP_MBITS + 1 + 3 + 1)) != 0); -+ } -+ assert(rm & (DP_HIDDEN_BIT << 3)); -+ DPNORMRET2(rs, re, rm, "mul", x, y); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_scalb.c linux-3.4.113/arch/nds32/math-emu/dp_scalb.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_scalb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_scalb.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,56 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_scalb(ieee754dp x, int n) -+{ -+ COMPXDP; -+ -+ CLEARCX; -+ -+ EXPLODEXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ return ieee754dp_nanxcpt(x, "scalb", x, n); -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ case IEEE754_CLASS_ZERO: -+ return x; -+ case IEEE754_CLASS_DNORM: -+ DPDNORMX; -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ DPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n); -+} -+ -+ieee754dp ieee754dp_ldexp(ieee754dp x, int n) -+{ -+ return ieee754dp_scalb(x, n); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_simple.c linux-3.4.113/arch/nds32/math-emu/dp_simple.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_simple.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_simple.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,87 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+int ieee754dp_finite(ieee754dp x) -+{ -+ return DPBEXP(x) != DP_EMAX + 1 + DP_EBIAS; -+} -+ -+ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y) -+{ -+ CLEARCX; -+ DPSIGN(x) = DPSIGN(y); -+ return x; -+} -+ -+ieee754dp ieee754dp_neg(ieee754dp x) -+{ -+ COMPXDP; -+ -+ EXPLODEXDP; -+ CLEARCX; -+ FLUSHXDP; -+ -+ /* -+ * Invert the sign ALWAYS to prevent an endless recursion on -+ * pow() in libc. -+ */ -+ /* quick fix up */ -+ DPSIGN(x) ^= 1; -+ -+ if (xc == IEEE754_CLASS_SNAN) { -+ ieee754dp y = ieee754dp_indef(); -+ SETCX(IEEE754_INVALID_OPERATION); -+ DPSIGN(y) = DPSIGN(x); -+ return ieee754dp_nanxcpt(y, "neg"); -+ } -+ -+ if (ieee754dp_isnan(x)) /* but not infinity */ -+ return ieee754dp_nanxcpt(x, "neg", x); -+ return x; -+} -+ -+ieee754dp ieee754dp_abs(ieee754dp x) -+{ -+ COMPXDP; -+ -+ EXPLODEXDP; -+ CLEARCX; -+ FLUSHXDP; -+ -+ if (xc == IEEE754_CLASS_SNAN) { -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "neg"); -+ } -+ -+ if (ieee754dp_isnan(x)) /* but not infinity */ -+ return ieee754dp_nanxcpt(x, "abs", x); -+ -+ /* quick fix up */ -+ DPSIGN(x) = 0; -+ return x; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_sqrt.c linux-3.4.113/arch/nds32/math-emu/dp_sqrt.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_sqrt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_sqrt.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,164 @@ -+/* IEEE754 floating point arithmetic -+ * double precision square root -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+static const unsigned table[] = { -+ 0, 1204, 3062, 5746, 9193, 13348, 18162, 23592, -+ 29598, 36145, 43202, 50740, 58733, 67158, 75992, -+ 85215, 83599, 71378, 60428, 50647, 41945, 34246, -+ 27478, 21581, 16499, 12183, 8588, 5674, 3403, -+ 1742, 661, 130 -+}; -+ -+ieee754dp ieee754dp_sqrt(ieee754dp x) -+{ -+ struct _ieee754_csr oldcsr; -+ ieee754dp y, z, t; -+ unsigned scalx, yh; -+ COMPXDP; -+ -+ EXPLODEXDP; -+ CLEARCX; -+ FLUSHXDP; -+ -+ /* x == INF or NAN? */ -+ switch (xc) { -+ case IEEE754_CLASS_QNAN: -+ /* sqrt(Nan) = Nan */ -+ return ieee754dp_nanxcpt(x, "sqrt"); -+ case IEEE754_CLASS_SNAN: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); -+ case IEEE754_CLASS_ZERO: -+ /* sqrt(0) = 0 */ -+ return x; -+ case IEEE754_CLASS_INF: -+ if (xs) { -+ /* sqrt(-Inf) = Nan */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); -+ } -+ /* sqrt(+Inf) = Inf */ -+ return x; -+ case IEEE754_CLASS_DNORM: -+ DPDNORMX; -+ /* fall through */ -+ case IEEE754_CLASS_NORM: -+ if (xs) { -+ /* sqrt(-x) = Nan */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sqrt"); -+ } -+ break; -+ } -+ -+ /* save old csr; switch off INX enable & flag; set RN rounding */ -+ oldcsr = ieee754_csr; -+ ieee754_csr.mx &= ~IEEE754_INEXACT; -+ ieee754_csr.sx &= ~IEEE754_INEXACT; -+ ieee754_csr.rm = IEEE754_RN; -+ -+ /* adjust exponent to prevent overflow */ -+ scalx = 0; -+ if (xe > 512) { /* x > 2**-512? */ -+ xe -= 512; /* x = x / 2**512 */ -+ scalx += 256; -+ } else if (xe < -512) { /* x < 2**-512? */ -+ xe += 512; /* x = x * 2**512 */ -+ scalx -= 256; -+ } -+ -+ y = x = builddp(0, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -+ -+ /* magic initial approximation to almost 8 sig. bits */ -+ yh = y.bits >> 32; -+ yh = (yh >> 1) + 0x1ff80000; -+ yh = yh - table[(yh >> 15) & 31]; -+ y.bits = ((u64) yh << 32) | (y.bits & 0xffffffff); -+ -+ /* Heron's rule once with correction to improve to ~18 sig. bits */ -+ /* t=x/y; y=y+t; py[n0]=py[n0]-0x00100006; py[n1]=0; */ -+ t = ieee754dp_div(x, y); -+ y = ieee754dp_add(y, t); -+ y.bits -= 0x0010000600000000LL; -+ y.bits &= 0xffffffff00000000LL; -+ -+ /* triple to almost 56 sig. bits: y ~= sqrt(x) to within 1 ulp */ -+ /* t=y*y; z=t; pt[n0]+=0x00100000; t+=z; z=(x-z)*y; */ -+ z = t = ieee754dp_mul(y, y); -+ t.parts.bexp += 0x001; -+ t = ieee754dp_add(t, z); -+ z = ieee754dp_mul(ieee754dp_sub(x, z), y); -+ -+ /* t=z/(t+x) ; pt[n0]+=0x00100000; y+=t; */ -+ t = ieee754dp_div(z, ieee754dp_add(t, x)); -+ t.parts.bexp += 0x001; -+ y = ieee754dp_add(y, t); -+ -+ /* twiddle last bit to force y correctly rounded */ -+ -+ /* set RZ, clear INEX flag */ -+ ieee754_csr.rm = IEEE754_RZ; -+ ieee754_csr.sx &= ~IEEE754_INEXACT; -+ -+ /* t=x/y; ...chopped quotient, possibly inexact */ -+ t = ieee754dp_div(x, y); -+ -+ if (ieee754_csr.sx & IEEE754_INEXACT || t.bits != y.bits) { -+ -+ if (!(ieee754_csr.sx & IEEE754_INEXACT)) -+ /* t = t-ulp */ -+ t.bits -= 1; -+ -+ /* add inexact to result status */ -+ oldcsr.cx |= IEEE754_INEXACT; -+ oldcsr.sx |= IEEE754_INEXACT; -+ -+ switch (oldcsr.rm) { -+ case IEEE754_RP: -+ y.bits += 1; -+ /* drop through */ -+ case IEEE754_RN: -+ t.bits += 1; -+ break; -+ } -+ -+ /* y=y+t; ...chopped sum */ -+ y = ieee754dp_add(y, t); -+ -+ /* adjust scalx for correctly rounded sqrt(x) */ -+ scalx -= 1; -+ } -+ -+ /* py[n0]=py[n0]+scalx; ...scale back y */ -+ y.parts.bexp += scalx; -+ -+ /* restore rounding mode, possibly set inexact */ -+ ieee754_csr = oldcsr; -+ -+ return y; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_sub.c linux-3.4.113/arch/nds32/math-emu/dp_sub.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_sub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_sub.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,187 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y) -+{ -+ COMPXDP; -+ COMPYDP; -+ -+ EXPLODEXDP; -+ EXPLODEYDP; -+ -+ CLEARCX; -+ -+ FLUSHXDP; -+ FLUSHYDP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_nanxcpt(ieee754dp_indef(), "sub", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ if (xs != ys) -+ return x; -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754dp_xcpt(ieee754dp_indef(), "sub", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ return ieee754dp_inf(ys ^ 1); -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ return x; -+ -+ /* Zero handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ if (xs != ys) -+ return x; -+ else -+ return ieee754dp_zero(ieee754_csr.rm == IEEE754_RD); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ return x; -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ /* quick fix up */ -+ DPSIGN(y) ^= 1; -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ DPDNORMX; -+ /* FAAL THOROUGH */ -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ /* normalize ym,ye */ -+ DPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ /* normalize xm,xe */ -+ DPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ /* flip sign of y and handle as add */ -+ ys ^= 1; -+ -+ assert(xm & DP_HIDDEN_BIT); -+ assert(ym & DP_HIDDEN_BIT); -+ -+ /* provide guard,round and stick bit dpace */ -+ xm <<= 3; -+ ym <<= 3; -+ -+ if (xe > ye) { -+ /* have to shift y fraction right to align -+ */ -+ int s = xe - ye; -+ ym = XDPSRS(ym, s); -+ ye += s; -+ } else if (ye > xe) { -+ /* have to shift x fraction right to align -+ */ -+ int s = ye - xe; -+ xm = XDPSRS(xm, s); -+ xe += s; -+ } -+ assert(xe == ye); -+ assert(xe <= DP_EMAX); -+ -+ if (xs == ys) { -+ /* generate 28 bit result of adding two 27 bit numbers -+ */ -+ xm = xm + ym; -+ xe = xe; -+ xs = xs; -+ -+ if (xm >> (DP_MBITS + 1 + 3)) { /* carry out */ -+ xm = XDPSRS1(xm); /* shift preserving sticky */ -+ xe++; -+ } -+ } else { -+ if (xm >= ym) { -+ xm = xm - ym; -+ xe = xe; -+ xs = xs; -+ } else { -+ xm = ym - xm; -+ xe = xe; -+ xs = ys; -+ } -+ if (xm == 0) { -+ if (ieee754_csr.rm == IEEE754_RD) -+ return ieee754dp_zero(1); /* round negative inf. => sign = -1 */ -+ else -+ return ieee754dp_zero(0); /* other round modes => sign = 1 */ -+ } -+ -+ /* normalize to rounding precision -+ */ -+ while ((xm >> (DP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ } -+ DPNORMRET2(xs, xe, xm, "sub", x, y); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_tint.c linux-3.4.113/arch/nds32/math-emu/dp_tint.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_tint.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_tint.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,121 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include -+#include "ieee754dp.h" -+ -+int ieee754dp_tint(ieee754dp x) -+{ -+ COMPXDP; -+ -+ CLEARCX; -+ -+ EXPLODEXDP; -+ FLUSHXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); -+ case IEEE754_CLASS_ZERO: -+ return 0; -+ case IEEE754_CLASS_DNORM: -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ if (xe > 31) { -+ /* Set invalid. We will only use overflow for floating -+ point overflow */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); -+ } -+ /* oh gawd */ -+ if (xe > DP_MBITS) { -+ xm <<= xe - DP_MBITS; -+ } else if (xe < DP_MBITS) { -+ u64 residue; -+ int round; -+ int sticky; -+ int odd; -+ -+ if (xe < -1) { -+ residue = xm; -+ round = 0; -+ sticky = residue != 0; -+ xm = 0; -+ } else { -+ residue = xm << (64 - DP_MBITS + xe); -+ round = (residue >> 63) != 0; -+ sticky = (residue << 1) != 0; -+ xm >>= DP_MBITS - xe; -+ } -+ /* Note: At this point upper 32 bits of xm are guaranteed -+ to be zero */ -+ odd = (xm & 0x1) != 0x0; -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ if (round && (sticky || odd)) -+ xm++; -+ break; -+ case IEEE754_RZ: -+ break; -+ case IEEE754_RU: /* toward +Infinity */ -+ if ((round || sticky) && !xs) -+ xm++; -+ break; -+ case IEEE754_RD: /* toward -Infinity */ -+ if ((round || sticky) && xs) -+ xm++; -+ break; -+ } -+ /* look for valid corner case 0x80000000 */ -+ if ((xm >> 31) != 0 && (xs == 0 || xm != 0x80000000)) { -+ /* This can happen after rounding */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754si_xcpt(ieee754si_indef(), "dp_tint", x); -+ } -+ if (round || sticky) -+ SETCX(IEEE754_INEXACT); -+ } -+ if (xs) -+ return -xm; -+ else -+ return xm; -+} -+ -+unsigned int ieee754dp_tuns(ieee754dp x) -+{ -+ ieee754dp hb = ieee754dp_1e31(); -+ -+ /* what if x < 0 ?? */ -+ if (ieee754dp_lt(x, hb)) -+ return (unsigned)ieee754dp_tint(x); -+ -+ return (unsigned)ieee754dp_tint(ieee754dp_sub(x, hb)) | -+ ((unsigned)1 << 31); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/dp_tlong.c linux-3.4.113/arch/nds32/math-emu/dp_tlong.c ---- linux-3.4.113.orig/arch/nds32/math-emu/dp_tlong.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/dp_tlong.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,123 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+s64 ieee754dp_tlong(ieee754dp x) -+{ -+ COMPXDP; -+ -+ CLEARCX; -+ -+ EXPLODEXDP; -+ FLUSHXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); -+ case IEEE754_CLASS_ZERO: -+ return 0; -+ case IEEE754_CLASS_DNORM: -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ if (xe >= 63) { -+ /* look for valid corner case */ -+ if (xe == 63 && xs && xm == DP_HIDDEN_BIT) -+ return -0x8000000000000000LL; -+ /* Set invalid. We will only use overflow for floating -+ point overflow */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); -+ } -+ /* oh gawd */ -+ if (xe > DP_MBITS) { -+ xm <<= xe - DP_MBITS; -+ } else if (xe < DP_MBITS) { -+ u64 residue; -+ int round; -+ int sticky; -+ int odd; -+ -+ if (xe < -1) { -+ residue = xm; -+ round = 0; -+ sticky = residue != 0; -+ xm = 0; -+ } else { -+ /* Shifting a u64 64 times does not work, -+ * so we do it in two steps. Be aware that xe -+ * may be -1 */ -+ residue = xm << (xe + 1); -+ residue <<= 63 - DP_MBITS; -+ round = (residue >> 63) != 0; -+ sticky = (residue << 1) != 0; -+ xm >>= DP_MBITS - xe; -+ } -+ odd = (xm & 0x1) != 0x0; -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ if (round && (sticky || odd)) -+ xm++; -+ break; -+ case IEEE754_RZ: -+ break; -+ case IEEE754_RU: /* toward +Infinity */ -+ if ((round || sticky) && !xs) -+ xm++; -+ break; -+ case IEEE754_RD: /* toward -Infinity */ -+ if ((round || sticky) && xs) -+ xm++; -+ break; -+ } -+ if ((xm >> 63) != 0) { -+ /* This can happen after rounding */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754di_xcpt(ieee754di_indef(), "dp_tlong", x); -+ } -+ if (round || sticky) -+ SETCX(IEEE754_INEXACT); -+ } -+ if (xs) -+ return -xm; -+ else -+ return xm; -+} -+ -+u64 ieee754dp_tulong(ieee754dp x) -+{ -+ ieee754dp hb = ieee754dp_1e63(); -+ -+ /* what if x < 0 ?? */ -+ if (ieee754dp_lt(x, hb)) -+ return (u64) ieee754dp_tlong(x); -+ -+ return (u64) ieee754dp_tlong(ieee754dp_sub(x, hb)) | (1ULL << 63); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/fpuemu.c linux-3.4.113/arch/nds32/math-emu/fpuemu.c ---- linux-3.4.113.orig/arch/nds32/math-emu/fpuemu.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/fpuemu.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,565 @@ -+/* -+ * linux/arch/nds32/math-emu/fpuemu.c: a nds32 coprocessor (fpu) instruction emulator -+ * -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com -+ * Copyright (C) 2000 MIPS Technologies, Inc. -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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. -+ * -+ * A complete emulator for MIPS coprocessor 1 instructions. This is -+ * required for #float(switch) or #float(trap), where it catches all -+ * COP1 instructions via the "CoProcessor Unusable" exception. -+ * -+ * More surprisingly it is also required for #float(ieee), to help out -+ * the hardware fpu at the boundaries of the IEEE-754 representation -+ * (denormalised values, infinities, underflow, etc). It is made -+ * quite nasty because emulation of some non-COP1 instructions is -+ * required, e.g. in branch delay slots. -+ * -+ * Note if you know that you won't have an fpu, then you'll get much -+ * better performance by compiling with -msoft-float! -+ */ -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "ieee754.h" -+#include "insn.h" -+#include "fpu_emulator.h" -+ -+/* Function which emulates a floating point instruction. */ -+ -+static int fpu_emu(struct pt_regs *, struct fpu_struct *, unsigned long); -+ -+/* Further private data for which no space exists in fpu_struct */ -+ -+struct fpu_emulator_stats fpuemustats; -+ -+/* rounding mode */ -+#define FPU_FPCSR_RN 0x0 /* nearest */ -+#define FPU_FPCSR_RU 0x1 /* towards +Infinity */ -+#define FPU_FPCSR_RD 0x2 /* towards -Infinity */ -+#define FPU_FPCSR_RZ 0x3 /* towards zero */ -+ -+/* Convert Mips rounding mode (0..3) to IEEE library modes. */ -+static const unsigned char ieee_rm[4] = { -+ [FPU_FPCSR_RN] = IEEE754_RN, -+ [FPU_FPCSR_RU] = IEEE754_RU, -+ [FPU_FPCSR_RD] = IEEE754_RD, -+ [FPU_FPCSR_RZ] = IEEE754_RZ, -+}; -+ -+/* Convert IEEE library modes to NDS32 rounding mode (0..3). */ -+static const unsigned char nds32_rm[4] = { -+ [IEEE754_RN] = FPU_FPCSR_RN, -+ [IEEE754_RZ] = FPU_FPCSR_RZ, -+ [IEEE754_RD] = FPU_FPCSR_RD, -+ [IEEE754_RU] = FPU_FPCSR_RU, -+}; -+ -+/* -+ * In the Linux kernel, we support selection of FPR format on the -+ * basis of the Status.FR bit. This does imply that, if a full 32 -+ * FPRs are desired, there needs to be a flip-flop that can be written -+ * to one at that bit position. In any case, O32 MIPS ABI uses -+ * only the even FPRs (Status.FR = 0). -+ */ -+ -+#define CP0_STATUS_FR_SUPPORT -+ -+#ifdef CP0_STATUS_FR_SUPPORT -+#define FR_BIT ST0_FR -+#else -+#define FR_BIT 0 -+#endif -+ -+#define SIFROMREG(si, x) ((si) = *((unsigned long *)ctx + x)) -+#define SITOREG(si, x) (*((unsigned long *)ctx + x)= (si)) -+ -+#ifdef __NDS32_EL__ -+#define DIFROMREG(di, x) ((di) = (unsigned long long)ptr[2*x] << 32 | (unsigned long long)ptr[2*x+1]) -+#define DITOREG(di, x) ptr[2*x] = (di) >> 32; ptr[2*x+1] = (unsigned long)(di) -+#else -+#define DIFROMREG(di, x) ((di) = (unsigned long long)ptr[2*x+1] << 32 | (unsigned long long)ptr[2*x]) -+#define DITOREG(di, x) ptr[2*x+1] = (di) >> 32; ptr[2*x] = (unsigned long)(di) -+#endif -+ -+#define SPFROMREG(sp, x) SIFROMREG((sp).bits, x) -+#define SPTOREG(sp, x) SITOREG((sp).bits, x) -+#define DPFROMREG(dp, x) DIFROMREG((dp).bits, x) -+#define DPTOREG(dp, x) DITOREG((dp).bits, x) -+ -+#define DEF3OP(name, p, f1, f2, f3) \ -+static ieee754##p fpemu_##p##_##name(ieee754##p r, ieee754##p s, \ -+ ieee754##p t) \ -+{ \ -+ struct _ieee754_csr ieee754_csr_save; \ -+ s = f1(s, t); \ -+ ieee754_csr_save = ieee754_csr; \ -+ s = f2(s, r); \ -+ ieee754_csr_save.cx |= ieee754_csr.cx; \ -+ ieee754_csr_save.sx |= ieee754_csr.sx; \ -+ s = f3(s); \ -+ ieee754_csr.cx |= ieee754_csr_save.cx; \ -+ ieee754_csr.sx |= ieee754_csr_save.sx; \ -+ return s; \ -+} -+ -+DEF3OP(madd, sp, ieee754sp_mul, ieee754sp_add,); -+DEF3OP(msub, sp, ieee754sp_mul, ieee754sp_sub,); -+DEF3OP(nmadd, sp, ieee754sp_mul, ieee754sp_add, ieee754sp_neg); -+DEF3OP(nmsub, sp, ieee754sp_mul, ieee754sp_sub, ieee754sp_neg); -+DEF3OP(madd, dp, ieee754dp_mul, ieee754dp_add,); -+DEF3OP(msub, dp, ieee754dp_mul, ieee754dp_sub,); -+DEF3OP(nmadd, dp, ieee754dp_mul, ieee754dp_add, ieee754dp_neg); -+DEF3OP(nmsub, dp, ieee754dp_mul, ieee754dp_sub, ieee754dp_neg); -+ -+/* -+ * Emulate the floating point instruction w/ denorm input pointed at by IPC. -+ * According to spec, only FPU arithmetic, data format conversion, and compare instructions. -+ */ -+ -+static int fpuEmulate(struct pt_regs *regs, struct fpu_struct *fpu) -+{ -+ unsigned long insn = 0, addr = regs->NDS32_ipc; -+ unsigned long emulpc, contpc; -+ unsigned char *pc = (void *)&insn; -+ char c; -+ int i = 0; -+ -+ for (i = 0; i < 4; i++) { -+ if (__get_user(c, (unsigned char *)addr++)) -+ return SIGBUS; -+ *pc++ = c; -+ } -+ -+ insn = be32_to_cpu(insn); -+ -+ emulpc = regs->NDS32_ipc; -+ contpc = regs->NDS32_ipc + 4; -+ -+ fpuemustats.emulated++; -+ switch (NDS32Insn_OPCODE(insn)) { -+ case cop0_op: -+ switch (NDS32Insn_OPCODE_COP0(insn)) { -+ -+ case fs1_op: -+ case fs2_op: -+ case fd1_op: -+ case fd2_op: -+ { -+ int sig; -+ -+ /* a real fpu computation instruction */ -+ if ((sig = fpu_emu(regs, fpu, insn))) -+ return sig; -+ } -+ break; -+ -+ default: -+ return SIGILL; -+ } -+ break; -+ default: -+ return SIGILL; -+ } -+ -+ /* we did it !! */ -+ regs->NDS32_ipc = contpc; -+ -+ return 0; -+} -+ -+/* -+ * Conversion table from NDS32 fcmp TYP -+ * cond = ieee754dp_cmp(x,y,IEEE754_UN,sig); -+ */ -+static const unsigned char cmptab[8] = { -+ IEEE754_CEQ, -+ IEEE754_CLT, -+ IEEE754_CLT | IEEE754_CEQ, -+ IEEE754_CUN, -+ 0, -+ 0, -+ 0, -+ 0, -+}; -+ -+/* -+ * Emulate a single FPU arithmetic instruction. -+ */ -+static int fpu_emu(struct pt_regs *xcp, struct fpu_struct *ctx, -+ unsigned long insn) -+{ -+ int rfmt; /* resulting format */ -+ unsigned rfpcsr = 0; /* resulting csr */ -+ unsigned long *ptr = (unsigned long *)ctx; -+ union { -+ ieee754dp d; -+ ieee754sp s; -+ int w; -+ } rv; /* resulting value */ -+ -+ fpuemustats.fpuops++; -+ switch (rfmt = NDS32Insn_OPCODE_COP0(insn)) { -+ case fs1_op:{ -+ union { -+ ieee754sp(*t) (ieee754sp, ieee754sp, ieee754sp); -+ ieee754sp(*b) (ieee754sp, ieee754sp); -+ ieee754sp(*u) (ieee754sp); -+ } handler; -+ -+ switch (NDS32Insn_OPCODE_BIT69(insn)) { -+ case fadds_op: -+ handler.b = ieee754sp_add; -+ goto scopbop; -+ case fsubs_op: -+ handler.b = ieee754sp_sub; -+ goto scopbop; -+ case fmadds_op: -+ handler.t = fpemu_sp_madd; -+ goto scoptop; -+ case fmsubs_op: -+ handler.t = fpemu_sp_msub; -+ goto scoptop; -+ case fnmadds_op: -+ handler.t = fpemu_sp_nmadd; -+ goto scoptop; -+ case fnmsubs_op: -+ handler.t = fpemu_sp_nmsub; -+ goto scoptop; -+ case fmuls_op: -+ handler.b = ieee754sp_mul; -+ goto scopbop; -+ case fdivs_op: -+ handler.b = ieee754sp_div; -+ goto scopbop; -+ -+ /* binary op on handler */ -+scoptop: -+ { -+ ieee754sp fd, fr, fs, ft; -+ -+ SPFROMREG(fr, -+ NDS32Insn_OPCODE_Rt(insn)); -+ SPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ SPFROMREG(ft, -+ NDS32Insn_OPCODE_Rb(insn)); -+ fd = (*handler.t) (fr, fs, ft); -+ SPTOREG(fd, NDS32Insn_OPCODE_Rt(insn)); -+ } -+scopbop: -+ { -+ ieee754sp fs, ft; -+ -+ SPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ SPFROMREG(ft, -+ NDS32Insn_OPCODE_Rb(insn)); -+ -+ rv.s = (*handler.b) (fs, ft); -+ goto copcsr; -+ } -+scopuop: -+ { -+ ieee754sp fs; -+ -+ SPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ rv.s = (*handler.u) (fs); -+ goto copcsr; -+ } -+copcsr: -+ if (ieee754_cxtest(IEEE754_INEXACT)) -+ rfpcsr |= FPCSR_mskIEX; -+ if (ieee754_cxtest(IEEE754_UNDERFLOW)) -+ rfpcsr |= FPCSR_mskUDF; -+ if (ieee754_cxtest(IEEE754_OVERFLOW)) -+ rfpcsr |= FPCSR_mskOVF; -+ if (ieee754_cxtest(IEEE754_ZERO_DIVIDE)) -+ rfpcsr |= FPCSR_mskDBZ; -+ if (ieee754_cxtest(IEEE754_INVALID_OPERATION)) -+ rfpcsr |= FPCSR_mskIVO; -+ break; -+ -+ case fs1_f2op_op: -+ switch (NDS32Insn_OPCODE_BIT1014(insn)) { -+ case fs2d_op:{ -+ ieee754sp fs; -+ SPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra -+ (insn)); -+ rv.d = ieee754dp_fsp(fs); -+ rfmt = fd1_op; -+ goto copcsr; -+ } -+ case fsqrts_op: -+ handler.u = ieee754sp_sqrt; -+ goto scopuop; -+ case fabss_op: -+ handler.u = ieee754sp_abs; -+ goto scopuop; -+ default: -+ return SIGILL; -+ } -+ default: -+ return SIGILL; -+ } -+ break; -+ } -+ -+ case fs2_op: -+ switch (NDS32Insn_OPCODE_BIT69(insn)) { -+ case fcmpeqs_op: -+ case fcmpeqs_e_op: -+ case fcmplts_op: -+ case fcmplts_e_op: -+ case fcmples_op: -+ case fcmples_e_op: -+ case fcmpuns_op: -+ case fcmpuns_e_op: -+ { -+ unsigned int cmpop = -+ NDS32Insn_OPCODE_BIT69(insn); -+ if (cmpop < 0x8) { -+ ieee754sp fs, ft; -+ -+ SPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ SPFROMREG(ft, -+ NDS32Insn_OPCODE_Rb(insn)); -+ rv.w = -+ ieee754sp_cmp(fs, ft, -+ cmptab[(cmpop >> 1) & -+ 0x7], -+ cmpop & 0x1); -+ if ((cmpop & 0x1) -+ && -+ ieee754_cxtest -+ (IEEE754_INVALID_OPERATION)) -+ rfpcsr = FPCSR_mskIVO; -+ else -+ goto copcsr; -+ } else -+ return SIGILL; -+ } -+ break; -+ -+ default: -+ return SIGILL; -+ } -+ break; -+ -+ case fd1_op: -+ { -+ union { -+ ieee754dp(*t) (ieee754dp, ieee754dp, ieee754dp); -+ ieee754dp(*b) (ieee754dp, ieee754dp); -+ ieee754dp(*u) (ieee754dp); -+ } handler; -+ -+ switch (NDS32Insn_OPCODE_BIT69(insn)) { -+ case faddd_op: -+ handler.b = ieee754dp_add; -+ goto dcopbop; -+ case fsubd_op: -+ handler.b = ieee754dp_sub; -+ goto dcopbop; -+ case fmaddd_op: -+ handler.t = fpemu_dp_madd; -+ goto tdcoptop; -+ case fmsubd_op: -+ handler.t = fpemu_dp_msub; -+ goto tdcoptop; -+ case fnmaddd_op: -+ handler.t = fpemu_dp_nmadd; -+ goto tdcoptop; -+ case fnmsubd_op: -+ handler.t = fpemu_dp_nmsub; -+ goto tdcoptop; -+ -+tdcoptop: -+ { -+ ieee754dp fd, fr, fs, ft; -+ -+ DPFROMREG(fr, -+ NDS32Insn_OPCODE_Rt(insn)); -+ DPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ DPFROMREG(ft, -+ NDS32Insn_OPCODE_Rb(insn)); -+ fd = (*handler.t) (fr, fs, ft); -+ DPTOREG(fd, NDS32Insn_OPCODE_Rt(insn)); -+ goto copcsr; -+ } -+ -+ case fmuld_op: -+ handler.b = ieee754dp_mul; -+ goto dcopbop; -+ case fdivd_op: -+ handler.b = ieee754dp_div; -+ goto dcopbop; -+ -+ /* binary op on handler */ -+dcopbop: { -+ ieee754dp fs, ft; -+ -+ DPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ DPFROMREG(ft, -+ NDS32Insn_OPCODE_Rb(insn)); -+ -+ rv.d = (*handler.b) (fs, ft); -+ goto copcsr; -+ } -+dcopuop: { -+ ieee754dp fs; -+ -+ DPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ rv.d = (*handler.u) (fs); -+ goto copcsr; -+ } -+ -+ case fd1_f2op_op: -+ switch (NDS32Insn_OPCODE_BIT1014(insn)) { -+ case fd2s_op:{ -+ ieee754dp fs; -+ -+ DPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra -+ (insn)); -+ rv.s = ieee754sp_fdp(fs); -+ rfmt = fd1_op; -+ goto copcsr; -+ } -+ case fsqrtd_op: -+ handler.u = ieee754dp_sqrt; -+ goto dcopuop; -+ case fabsd_op: -+ handler.u = ieee754dp_abs; -+ goto dcopuop; -+ default: -+ return SIGILL; -+ } -+ default: -+ return SIGILL; -+ } -+ break; -+ } -+ -+ case fd2_op: -+ switch (NDS32Insn_OPCODE_BIT69(insn)) { -+ case fcmpeqd_op: -+ case fcmpeqd_e_op: -+ case fcmpltd_op: -+ case fcmpltd_e_op: -+ case fcmpled_op: -+ case fcmpled_e_op: -+ case fcmpund_op: -+ case fcmpund_e_op: -+ { -+ unsigned cmpop = NDS32Insn_OPCODE_BIT69(insn); -+ if (cmpop < 0x8) { -+ ieee754dp fs, ft; -+ -+ DPFROMREG(fs, -+ NDS32Insn_OPCODE_Ra(insn)); -+ DPFROMREG(ft, -+ NDS32Insn_OPCODE_Rb(insn)); -+ rv.w = -+ ieee754dp_cmp(fs, ft, -+ cmptab[(cmpop >> 1) & -+ 0x7], -+ cmpop & 0x1); -+ rfmt = fs2_op; -+ if ((cmpop & 0x1) -+ && -+ ieee754_cxtest -+ (IEEE754_INVALID_OPERATION)) -+ rfpcsr = FPCSR_mskIVO; -+ else -+ goto copcsr; -+ } else -+ return SIGILL; -+ } -+ break; -+ default: -+ return SIGILL; -+ } -+ break; -+ -+ default: -+ return SIGILL; -+ } -+ -+ /* -+ * Now we can safely write the result back to the register file. -+ */ -+ switch (rfmt) { -+ case fd1_op: -+ case fd2_op: -+ DPTOREG(rv.d, NDS32Insn_OPCODE_Rt(insn)); -+ break; -+ case fs1_op: -+ case fs2_op: -+ SPTOREG(rv.s, NDS32Insn_OPCODE_Rt(insn)); -+ break; -+ default: -+ return SIGILL; -+ } -+ -+ /* -+ * Update the fpu CSR register for this operation. -+ * If an exception is required, generate a tidy SIGFPE exception, -+ * without updating the result register. -+ * Note: cause exception bits do not accumulate, they are rewritten -+ * for each op; only the flag/sticky bits accumulate. -+ */ -+ ctx->fpcsr = (ctx->fpcsr & ~FPCSR_mskALL) | rfpcsr; -+ if ((ctx->fpcsr << 5) & ctx->fpcsr & FPCSR_mskALLE) { -+ return SIGFPE; -+ } -+ -+ return 0; -+} -+ -+int do_fpu_denorm(struct pt_regs *regs, struct fpu_struct *fpu) -+{ -+ int sig = 0; -+ -+ /* -+ * The 'ieee754_csr' is an alias of -+ * fpcsr->RM. No need to copy fpcsr->RM to -+ * ieee754_csr. But ieee754_csr.rm is ieee -+ * library modes. (not NDS32 rounding mode) -+ */ -+ /* convert to ieee library modes */ -+ ieee754_csr.rm = ieee_rm[ieee754_csr.rm]; -+ sig = fpuEmulate(regs, fpu); -+ /* revert to NDS32 rounding mode */ -+ ieee754_csr.rm = nds32_rm[ieee754_csr.rm]; -+ -+ return sig; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/fpu_emulator.h linux-3.4.113/arch/nds32/math-emu/fpu_emulator.h ---- linux-3.4.113.orig/arch/nds32/math-emu/fpu_emulator.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/fpu_emulator.h 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,36 @@ -+/* -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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. -+ * -+ * Further private data for which no space exists in mips_fpu_struct. -+ * This should be subsumed into the mips_fpu_struct structure as -+ * defined in processor.h as soon as the absurd wired absolute assembler -+ * offsets become dynamic at compile time. -+ * -+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com -+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -+ */ -+#ifndef _ASM_FPU_EMULATOR_H -+#define _ASM_FPU_EMULATOR_H -+ -+struct fpu_emulator_stats { -+ unsigned int emulated; -+ unsigned int loads; -+ unsigned int stores; -+ unsigned int fpuops; -+ unsigned int errors; -+}; -+ -+extern struct fpu_emulator_stats fpuemustats; -+ -+#endif /* _ASM_FPU_EMULATOR_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754.c linux-3.4.113/arch/nds32/math-emu/ieee754.c ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,125 @@ -+/* ieee754 floating point arithmetic -+ * single and double precision -+ * -+ * BUGS -+ * not much dp done -+ * doesn't generate IEEE754_INEXACT -+ * -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754int.h" -+#include "ieee754sp.h" -+#include "ieee754dp.h" -+ -+#define DP_EBIAS 1023 -+#define DP_EMIN (-1022) -+#define DP_EMAX 1023 -+ -+#define SP_EBIAS 127 -+#define SP_EMIN (-126) -+#define SP_EMAX 127 -+ -+/* special constants -+*/ -+ -+#if (defined(BYTE_ORDER) && BYTE_ORDER == LITTLE_ENDIAN) || defined(__NDS32_EL__) -+#define SPSTR(s, b, m) {m, b, s} -+#define DPSTR(s, b, mh, ml) {ml, mh, b, s} -+#endif -+ -+#ifdef __NDS32_EB__ -+#define SPSTR(s, b, m) {s, b, m} -+#define DPSTR(s, b, mh, ml) {s, b, mh, ml} -+#endif -+ -+const struct ieee754dp_konst __ieee754dp_spcvals[] = { -+ DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* + zero */ -+ DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 0), /* - zero */ -+ DPSTR(0, DP_EBIAS, 0, 0), /* + 1.0 */ -+ DPSTR(1, DP_EBIAS, 0, 0), /* - 1.0 */ -+ DPSTR(0, 3 + DP_EBIAS, 0x40000, 0), /* + 10.0 */ -+ DPSTR(1, 3 + DP_EBIAS, 0x40000, 0), /* - 10.0 */ -+ DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* + infinity */ -+ DPSTR(1, DP_EMAX + 1 + DP_EBIAS, 0, 0), /* - infinity */ -+ DPSTR(0, DP_EMAX + 1 + DP_EBIAS, 0x7FFFF, 0xFFFFFFFF), /* + indef quiet Nan */ -+ DPSTR(0, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* + max */ -+ DPSTR(1, DP_EMAX + DP_EBIAS, 0xFFFFF, 0xFFFFFFFF), /* - max */ -+ DPSTR(0, DP_EMIN + DP_EBIAS, 0, 0), /* + min normal */ -+ DPSTR(1, DP_EMIN + DP_EBIAS, 0, 0), /* - min normal */ -+ DPSTR(0, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* + min denormal */ -+ DPSTR(1, DP_EMIN - 1 + DP_EBIAS, 0, 1), /* - min denormal */ -+ DPSTR(0, 31 + DP_EBIAS, 0, 0), /* + 1.0e31 */ -+ DPSTR(0, 63 + DP_EBIAS, 0, 0), /* + 1.0e63 */ -+}; -+ -+const struct ieee754sp_konst __ieee754sp_spcvals[] = { -+ SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 0), /* + zero */ -+ SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 0), /* - zero */ -+ SPSTR(0, SP_EBIAS, 0), /* + 1.0 */ -+ SPSTR(1, SP_EBIAS, 0), /* - 1.0 */ -+ SPSTR(0, 3 + SP_EBIAS, 0x200000), /* + 10.0 */ -+ SPSTR(1, 3 + SP_EBIAS, 0x200000), /* - 10.0 */ -+ SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0), /* + infinity */ -+ SPSTR(1, SP_EMAX + 1 + SP_EBIAS, 0), /* - infinity */ -+ SPSTR(0, SP_EMAX + 1 + SP_EBIAS, 0x3FFFFF), /* + indef quiet Nan */ -+ SPSTR(0, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* + max normal */ -+ SPSTR(1, SP_EMAX + SP_EBIAS, 0x7FFFFF), /* - max normal */ -+ SPSTR(0, SP_EMIN + SP_EBIAS, 0), /* + min normal */ -+ SPSTR(1, SP_EMIN + SP_EBIAS, 0), /* - min normal */ -+ SPSTR(0, SP_EMIN - 1 + SP_EBIAS, 1), /* + min denormal */ -+ SPSTR(1, SP_EMIN - 1 + SP_EBIAS, 1), /* - min denormal */ -+ SPSTR(0, 31 + SP_EBIAS, 0), /* + 1.0e31 */ -+ SPSTR(0, 63 + SP_EBIAS, 0), /* + 1.0e63 */ -+}; -+ -+int ieee754si_xcpt(int r, const char *op, ...) -+{ -+ struct ieee754xctx ax; -+ -+ if (!TSTX()) -+ return r; -+ ax.op = op; -+ ax.rt = IEEE754_RT_SI; -+ ax.rv.si = r; -+ va_start(ax.ap, op); -+ ieee754_xcpt(&ax); -+ va_end(ax.ap); -+ return ax.rv.si; -+} -+ -+s64 ieee754di_xcpt(s64 r, const char *op, ...) -+{ -+ struct ieee754xctx ax; -+ -+ if (!TSTX()) -+ return r; -+ ax.op = op; -+ ax.rt = IEEE754_RT_DI; -+ ax.rv.di = r; -+ va_start(ax.ap, op); -+ ieee754_xcpt(&ax); -+ va_end(ax.ap); -+ return ax.rv.di; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754d.c linux-3.4.113/arch/nds32/math-emu/ieee754d.c ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754d.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754d.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,134 @@ -+/* -+ * Some debug functions -+ * -+ * MIPS floating point support -+ * -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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. -+ * -+ * Nov 7, 2000 -+ * Modified to build and operate in Linux kernel environment. -+ * -+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com -+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -+ */ -+ -+#include -+#include "ieee754.h" -+ -+#define DP_EBIAS 1023 -+#define DP_EMIN (-1022) -+#define DP_EMAX 1023 -+#define DP_FBITS 52 -+ -+#define SP_EBIAS 127 -+#define SP_EMIN (-126) -+#define SP_EMAX 127 -+#define SP_FBITS 23 -+ -+#define DP_MBIT(x) ((u64)1 << (x)) -+#define DP_HIDDEN_BIT DP_MBIT(DP_FBITS) -+#define DP_SIGN_BIT DP_MBIT(63) -+ -+#define SP_MBIT(x) ((u32)1 << (x)) -+#define SP_HIDDEN_BIT SP_MBIT(SP_FBITS) -+#define SP_SIGN_BIT SP_MBIT(31) -+ -+#define SPSIGN(sp) (sp.parts.sign) -+#define SPBEXP(sp) (sp.parts.bexp) -+#define SPMANT(sp) (sp.parts.mant) -+ -+#define DPSIGN(dp) (dp.parts.sign) -+#define DPBEXP(dp) (dp.parts.bexp) -+#define DPMANT(dp) (dp.parts.mant) -+ -+ieee754dp ieee754dp_dump(char *m, ieee754dp x) -+{ -+ int i; -+ -+ printk("%s", m); -+ printk("<%08x,%08x>\n", (unsigned)(x.bits >> 32), (unsigned)x.bits); -+ printk("\t="); -+ switch (ieee754dp_class(x)) { -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_SNAN: -+ printk("Nan %c", DPSIGN(x) ? '-' : '+'); -+ for (i = DP_FBITS - 1; i >= 0; i--) -+ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); -+ break; -+ case IEEE754_CLASS_INF: -+ printk("%cInfinity", DPSIGN(x) ? '-' : '+'); -+ break; -+ case IEEE754_CLASS_ZERO: -+ printk("%cZero", DPSIGN(x) ? '-' : '+'); -+ break; -+ case IEEE754_CLASS_DNORM: -+ printk("%c0.", DPSIGN(x) ? '-' : '+'); -+ for (i = DP_FBITS - 1; i >= 0; i--) -+ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); -+ printk("e%d", DPBEXP(x) - DP_EBIAS); -+ break; -+ case IEEE754_CLASS_NORM: -+ printk("%c1.", DPSIGN(x) ? '-' : '+'); -+ for (i = DP_FBITS - 1; i >= 0; i--) -+ printk("%c", DPMANT(x) & DP_MBIT(i) ? '1' : '0'); -+ printk("e%d", DPBEXP(x) - DP_EBIAS); -+ break; -+ default: -+ printk("Illegal/Unknown IEEE754 value class"); -+ } -+ printk("\n"); -+ return x; -+} -+ -+ieee754sp ieee754sp_dump(char *m, ieee754sp x) -+{ -+ int i; -+ -+ printk("%s=", m); -+ printk("<%08x>\n", (unsigned)x.bits); -+ printk("\t="); -+ switch (ieee754sp_class(x)) { -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_SNAN: -+ printk("Nan %c", SPSIGN(x) ? '-' : '+'); -+ for (i = SP_FBITS - 1; i >= 0; i--) -+ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); -+ break; -+ case IEEE754_CLASS_INF: -+ printk("%cInfinity", SPSIGN(x) ? '-' : '+'); -+ break; -+ case IEEE754_CLASS_ZERO: -+ printk("%cZero", SPSIGN(x) ? '-' : '+'); -+ break; -+ case IEEE754_CLASS_DNORM: -+ printk("%c0.", SPSIGN(x) ? '-' : '+'); -+ for (i = SP_FBITS - 1; i >= 0; i--) -+ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); -+ printk("e%d", SPBEXP(x) - SP_EBIAS); -+ break; -+ case IEEE754_CLASS_NORM: -+ printk("%c1.", SPSIGN(x) ? '-' : '+'); -+ for (i = SP_FBITS - 1; i >= 0; i--) -+ printk("%c", SPMANT(x) & SP_MBIT(i) ? '1' : '0'); -+ printk("e%d", SPBEXP(x) - SP_EBIAS); -+ break; -+ default: -+ printk("Illegal/Unknown IEEE754 value class"); -+ } -+ printk("\n"); -+ return x; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754dp.c linux-3.4.113/arch/nds32/math-emu/ieee754dp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754dp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754dp.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,239 @@ -+/* IEEE754 floating point arithmetic -+ * double precision: common utilities -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754dp.h" -+ -+int ieee754dp_class(ieee754dp x) -+{ -+ COMPXDP; -+ EXPLODEXDP; -+ return xc; -+} -+ -+int ieee754dp_isnan(ieee754dp x) -+{ -+ return ieee754dp_class(x) >= IEEE754_CLASS_SNAN; -+} -+ -+int ieee754dp_issnan(ieee754dp x) -+{ -+ assert(ieee754dp_isnan(x)); -+ return ((DPMANT(x) & DP_MBIT(DP_MBITS - 1)) == DP_MBIT(DP_MBITS - 1)); -+} -+ -+ieee754dp ieee754dp_xcpt(ieee754dp r, const char *op, ...) -+{ -+ struct ieee754xctx ax; -+ if (!TSTX()) -+ return r; -+ -+ ax.op = op; -+ ax.rt = IEEE754_RT_DP; -+ ax.rv.dp = r; -+ va_start(ax.ap, op); -+ ieee754_xcpt(&ax); -+ va_end(ax.ap); -+ return ax.rv.dp; -+} -+ -+ieee754dp ieee754dp_nanxcpt(ieee754dp r, const char *op, ...) -+{ -+ struct ieee754xctx ax; -+ -+ assert(ieee754dp_isnan(r)); -+ -+ if (!ieee754dp_issnan(r)) /* QNAN does not cause invalid op !! */ -+ return r; -+ -+ if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { -+ /* not enabled convert to a quiet NaN */ -+ DPMANT(r) &= (~DP_MBIT(DP_MBITS - 1)); -+ if (ieee754dp_isnan(r)) -+ return r; -+ else -+ return ieee754dp_indef(); -+ } -+ -+ ax.op = op; -+ ax.rt = 0; -+ ax.rv.dp = r; -+ va_start(ax.ap, op); -+ ieee754_xcpt(&ax); -+ va_end(ax.ap); -+ return ax.rv.dp; -+} -+ -+ieee754dp ieee754dp_bestnan(ieee754dp x, ieee754dp y) -+{ -+ assert(ieee754dp_isnan(x)); -+ assert(ieee754dp_isnan(y)); -+ -+ if (DPMANT(x) > DPMANT(y)) -+ return x; -+ else -+ return y; -+} -+ -+static u64 get_rounding(int sn, u64 xm) -+{ -+ /* inexact must round of 3 bits -+ */ -+ if (xm & (DP_MBIT(3) - 1)) { -+ switch (ieee754_csr.rm) { -+ case IEEE754_RZ: -+ break; -+ case IEEE754_RN: -+ xm += 0x3 + ((xm >> 3) & 1); -+ /* xm += (xm&0x8)?0x4:0x3 */ -+ break; -+ case IEEE754_RU: /* toward +Infinity */ -+ if (!sn) /* ?? */ -+ xm += 0x8; -+ break; -+ case IEEE754_RD: /* toward -Infinity */ -+ if (sn) /* ?? */ -+ xm += 0x8; -+ break; -+ } -+ } -+ return xm; -+} -+ -+/* generate a normal/denormal number with over,under handling -+ * sn is sign -+ * xe is an unbiased exponent -+ * xm is 3bit extended precision value. -+ */ -+ieee754dp ieee754dp_format(int sn, int xe, u64 xm) -+{ -+ assert(xm); /* we don't gen exact zeros (probably should) */ -+ -+ assert((xm >> (DP_MBITS + 1 + 3)) == 0); /* no execess */ -+ assert(xm & (DP_HIDDEN_BIT << 3)); -+ -+ if (xe < DP_EMIN) { -+ /* strip lower bits */ -+ int es = DP_EMIN - xe; -+ -+ if (ieee754_csr.nod) { -+ SETCX(IEEE754_UNDERFLOW); -+ SETCX(IEEE754_INEXACT); -+ -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ return ieee754dp_zero(sn); -+ case IEEE754_RZ: -+ return ieee754dp_zero(sn); -+ case IEEE754_RU: /* toward +Infinity */ -+ if (sn == 0) -+ return ieee754dp_min(0); -+ else -+ return ieee754dp_zero(1); -+ case IEEE754_RD: /* toward -Infinity */ -+ if (sn == 0) -+ return ieee754dp_zero(0); -+ else -+ return ieee754dp_min(1); -+ } -+ } -+ -+ if (xe == DP_EMIN - 1 -+ && get_rounding(sn, xm) >> (DP_MBITS + 1 + 3)) { -+ /* Not tiny after rounding */ -+ SETCX(IEEE754_INEXACT); -+ xm = get_rounding(sn, xm); -+ xm >>= 1; -+ /* Clear grs bits */ -+ xm &= ~(DP_MBIT(3) - 1); -+ xe++; -+ } else { -+ /* sticky right shift es bits -+ */ -+ xm = XDPSRS(xm, es); -+ xe += es; -+ assert((xm & (DP_HIDDEN_BIT << 3)) == 0); -+ assert(xe == DP_EMIN); -+ } -+ } -+ if (xm & (DP_MBIT(3) - 1)) { -+ SETCX(IEEE754_INEXACT); -+ if ((xm & (DP_HIDDEN_BIT << 3)) == 0) { -+ SETCX(IEEE754_UNDERFLOW); -+ } -+ -+ /* inexact must round of 3 bits -+ */ -+ xm = get_rounding(sn, xm); -+ /* adjust exponent for rounding add overflowing -+ */ -+ if (xm >> (DP_MBITS + 3 + 1)) { -+ /* add causes mantissa overflow */ -+ xm >>= 1; -+ xe++; -+ } -+ } -+ /* strip grs bits */ -+ xm >>= 3; -+ -+ assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ -+ assert(xe >= DP_EMIN); -+ -+ if (xe > DP_EMAX) { -+ SETCX(IEEE754_OVERFLOW); -+ SETCX(IEEE754_INEXACT); -+ /* -O can be table indexed by (rm,sn) */ -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ return ieee754dp_inf(sn); -+ case IEEE754_RZ: -+ return ieee754dp_max(sn); -+ case IEEE754_RU: /* toward +Infinity */ -+ if (sn == 0) -+ return ieee754dp_inf(0); -+ else -+ return ieee754dp_max(1); -+ case IEEE754_RD: /* toward -Infinity */ -+ if (sn == 0) -+ return ieee754dp_max(0); -+ else -+ return ieee754dp_inf(1); -+ } -+ } -+ /* gen norm/denorm/zero */ -+ -+ if ((xm & DP_HIDDEN_BIT) == 0) { -+ /* we underflow (tiny/zero) */ -+ assert(xe == DP_EMIN); -+ if (ieee754_csr.mx & IEEE754_UNDERFLOW) -+ SETCX(IEEE754_UNDERFLOW); -+ return builddp(sn, DP_EMIN - 1 + DP_EBIAS, xm); -+ } else { -+ assert((xm >> (DP_MBITS + 1)) == 0); /* no execess */ -+ assert(xm & DP_HIDDEN_BIT); -+ -+ return builddp(sn, xe + DP_EBIAS, xm & ~DP_HIDDEN_BIT); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754dp.h linux-3.4.113/arch/nds32/math-emu/ieee754dp.h ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754dp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754dp.h 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,83 @@ -+/* -+ * IEEE754 floating point -+ * double precision internal header file -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+ -+#include "ieee754int.h" -+ -+#define assert(expr) ((void)0) -+ -+/* 3bit extended double precision sticky right shift */ -+#define XDPSRS(v,rs) \ -+ ((rs > (DP_MBITS+3))?1:((v) >> (rs)) | ((v) << (64-(rs)) != 0)) -+ -+#define XDPSRSX1() \ -+ (xe++, (xm = (xm >> 1) | (xm & 1))) -+ -+#define XDPSRS1(v) \ -+ (((v) >> 1) | ((v) & 1)) -+ -+/* convert denormal to normalized with extended exponent */ -+#define DPDNORMx(m,e) \ -+ while( (m >> DP_MBITS) == 0) { m <<= 1; e--; } -+#define DPDNORMX DPDNORMx(xm, xe) -+#define DPDNORMY DPDNORMx(ym, ye) -+ -+static inline ieee754dp builddp(int s, int bx, u64 m) -+{ -+ ieee754dp r; -+ -+ assert((s) == 0 || (s) == 1); -+ assert((bx) >= DP_EMIN - 1 + DP_EBIAS -+ && (bx) <= DP_EMAX + 1 + DP_EBIAS); -+ assert(((m) >> DP_MBITS) == 0); -+ -+ r.parts.sign = s; -+ r.parts.bexp = bx; -+ r.parts.mant = m; -+ return r; -+} -+ -+extern int ieee754dp_isnan(ieee754dp); -+extern int ieee754dp_issnan(ieee754dp); -+extern int ieee754si_xcpt(int, const char *, ...); -+extern s64 ieee754di_xcpt(s64, const char *, ...); -+extern ieee754dp ieee754dp_xcpt(ieee754dp, const char *, ...); -+extern ieee754dp ieee754dp_nanxcpt(ieee754dp, const char *, ...); -+extern ieee754dp ieee754dp_bestnan(ieee754dp, ieee754dp); -+extern ieee754dp ieee754dp_format(int, int, u64); -+ -+ -+#define DPNORMRET2(s, e, m, name, a0, a1) \ -+{ \ -+ ieee754dp V = ieee754dp_format(s, e, m); \ -+ if(TSTX()) \ -+ return ieee754dp_xcpt(V, name, a0, a1); \ -+ else \ -+ return V; \ -+} -+ -+#define DPNORMRET1(s, e, m, name, a0) DPNORMRET2(s, e, m, name, a0, a0) -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754.h linux-3.4.113/arch/nds32/math-emu/ieee754.h ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754.h 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,467 @@ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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. -+ * -+ * Nov 7, 2000 -+ * Modification to allow integration with Linux kernel -+ * -+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgard, carstenl@mips.com -+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -+ */ -+#ifndef __ARCH_MIPS_MATH_EMU_IEEE754_H -+#define __ARCH_MIPS_MATH_EMU_IEEE754_H -+ -+#include -+#include -+#include -+ -+/* -+ * Not very pretty, but the Linux kernel's normal va_list definition -+ * does not allow it to be used as a structure element, as it is here. -+ */ -+#ifndef _STDARG_H -+#include -+#endif -+ -+#ifdef __LITTLE_ENDIAN -+struct ieee754dp_konst { -+ unsigned mantlo:32; -+ unsigned manthi:20; -+ unsigned bexp:11; -+ unsigned sign:1; -+}; -+struct ieee754sp_konst { -+ unsigned mant:23; -+ unsigned bexp:8; -+ unsigned sign:1; -+}; -+ -+typedef union _ieee754dp { -+ struct ieee754dp_konst oparts; -+ struct { -+ u64 mant:52; -+ unsigned int bexp:11; -+ unsigned int sign:1; -+ } parts; -+ u64 bits; -+ double d; -+} ieee754dp; -+ -+typedef union _ieee754sp { -+ struct ieee754sp_konst parts; -+ float f; -+ u32 bits; -+} ieee754sp; -+#endif -+ -+#ifdef __BIG_ENDIAN -+struct ieee754dp_konst { -+ unsigned sign:1; -+ unsigned bexp:11; -+ unsigned manthi:20; -+ unsigned mantlo:32; -+}; -+ -+typedef union _ieee754dp { -+ struct ieee754dp_konst oparts; -+ struct { -+ unsigned int sign:1; -+ unsigned int bexp:11; -+ u64 mant:52; -+ } parts; -+ double d; -+ u64 bits; -+} ieee754dp; -+ -+struct ieee754sp_konst { -+ unsigned sign:1; -+ unsigned bexp:8; -+ unsigned mant:23; -+}; -+ -+typedef union _ieee754sp { -+ struct ieee754sp_konst parts; -+ float f; -+ u32 bits; -+} ieee754sp; -+#endif -+ -+/* -+ * single precision (often aka float) -+*/ -+int ieee754sp_finite(ieee754sp x); -+int ieee754sp_class(ieee754sp x); -+ -+ieee754sp ieee754sp_abs(ieee754sp x); -+ieee754sp ieee754sp_neg(ieee754sp x); -+ieee754sp ieee754sp_scalb(ieee754sp x, int); -+ieee754sp ieee754sp_logb(ieee754sp x); -+ -+/* x with sign of y */ -+ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y); -+ -+ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y); -+ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y); -+ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y); -+ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y); -+ -+ieee754sp ieee754sp_fint(int x); -+ieee754sp ieee754sp_funs(unsigned x); -+ieee754sp ieee754sp_flong(s64 x); -+ieee754sp ieee754sp_fulong(u64 x); -+ieee754sp ieee754sp_fdp(ieee754dp x); -+ -+int ieee754sp_tint(ieee754sp x); -+unsigned int ieee754sp_tuns(ieee754sp x); -+s64 ieee754sp_tlong(ieee754sp x); -+u64 ieee754sp_tulong(ieee754sp x); -+ -+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cop, int sig); -+/* -+ * basic sp math -+ */ -+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip); -+ieee754sp ieee754sp_frexp(ieee754sp x, int *exp); -+ieee754sp ieee754sp_ldexp(ieee754sp x, int exp); -+ -+ieee754sp ieee754sp_ceil(ieee754sp x); -+ieee754sp ieee754sp_floor(ieee754sp x); -+ieee754sp ieee754sp_trunc(ieee754sp x); -+ -+ieee754sp ieee754sp_sqrt(ieee754sp x); -+ -+/* -+ * double precision (often aka double) -+*/ -+int ieee754dp_finite(ieee754dp x); -+int ieee754dp_class(ieee754dp x); -+ -+/* x with sign of y */ -+ieee754dp ieee754dp_copysign(ieee754dp x, ieee754dp y); -+ -+ieee754dp ieee754dp_add(ieee754dp x, ieee754dp y); -+ieee754dp ieee754dp_sub(ieee754dp x, ieee754dp y); -+ieee754dp ieee754dp_mul(ieee754dp x, ieee754dp y); -+ieee754dp ieee754dp_div(ieee754dp x, ieee754dp y); -+ -+ieee754dp ieee754dp_abs(ieee754dp x); -+ieee754dp ieee754dp_neg(ieee754dp x); -+ieee754dp ieee754dp_scalb(ieee754dp x, int); -+ -+/* return exponent as integer in floating point format -+ */ -+ieee754dp ieee754dp_logb(ieee754dp x); -+ -+ieee754dp ieee754dp_fint(int x); -+ieee754dp ieee754dp_funs(unsigned x); -+ieee754dp ieee754dp_flong(s64 x); -+ieee754dp ieee754dp_fulong(u64 x); -+ieee754dp ieee754dp_fsp(ieee754sp x); -+ -+ieee754dp ieee754dp_ceil(ieee754dp x); -+ieee754dp ieee754dp_floor(ieee754dp x); -+ieee754dp ieee754dp_trunc(ieee754dp x); -+ -+int ieee754dp_tint(ieee754dp x); -+unsigned int ieee754dp_tuns(ieee754dp x); -+s64 ieee754dp_tlong(ieee754dp x); -+u64 ieee754dp_tulong(ieee754dp x); -+ -+int ieee754dp_cmp(ieee754dp x, ieee754dp y, int cop, int sig); -+/* -+ * basic sp math -+ */ -+ieee754dp ieee754dp_modf(ieee754dp x, ieee754dp * ip); -+ieee754dp ieee754dp_frexp(ieee754dp x, int *exp); -+ieee754dp ieee754dp_ldexp(ieee754dp x, int exp); -+ -+ieee754dp ieee754dp_ceil(ieee754dp x); -+ieee754dp ieee754dp_floor(ieee754dp x); -+ieee754dp ieee754dp_trunc(ieee754dp x); -+ -+ieee754dp ieee754dp_sqrt(ieee754dp x); -+ -+ -+ -+/* 5 types of floating point number -+*/ -+#define IEEE754_CLASS_NORM 0x00 -+#define IEEE754_CLASS_ZERO 0x01 -+#define IEEE754_CLASS_DNORM 0x02 -+#define IEEE754_CLASS_INF 0x03 -+#define IEEE754_CLASS_SNAN 0x04 -+#define IEEE754_CLASS_QNAN 0x05 -+ -+/* exception numbers */ -+#define IEEE754_INVALID_OPERATION 0x01 -+#define IEEE754_ZERO_DIVIDE 0x02 -+#define IEEE754_OVERFLOW 0x04 -+#define IEEE754_UNDERFLOW 0x08 -+#define IEEE754_INEXACT 0x10 -+ -+/* cmp operators -+*/ -+#define IEEE754_CLT 0x01 -+#define IEEE754_CEQ 0x02 -+#define IEEE754_CGT 0x04 -+#define IEEE754_CUN 0x08 -+ -+/* rounding mode -+*/ -+#define IEEE754_RN 0 /* round to nearest */ -+#define IEEE754_RZ 1 /* round toward zero */ -+#define IEEE754_RD 2 /* round toward -Infinity */ -+#define IEEE754_RU 3 /* round toward +Infinity */ -+ -+/* other naming */ -+#define IEEE754_RM IEEE754_RD -+#define IEEE754_RP IEEE754_RU -+ -+/* "normal" comparisons -+*/ -+static inline int ieee754sp_eq(ieee754sp x, ieee754sp y) -+{ -+ return ieee754sp_cmp(x, y, IEEE754_CEQ, 0); -+} -+ -+static inline int ieee754sp_ne(ieee754sp x, ieee754sp y) -+{ -+ return ieee754sp_cmp(x, y, -+ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0); -+} -+ -+static inline int ieee754sp_lt(ieee754sp x, ieee754sp y) -+{ -+ return ieee754sp_cmp(x, y, IEEE754_CLT, 0); -+} -+ -+static inline int ieee754sp_le(ieee754sp x, ieee754sp y) -+{ -+ return ieee754sp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0); -+} -+ -+static inline int ieee754sp_gt(ieee754sp x, ieee754sp y) -+{ -+ return ieee754sp_cmp(x, y, IEEE754_CGT, 0); -+} -+ -+ -+static inline int ieee754sp_ge(ieee754sp x, ieee754sp y) -+{ -+ return ieee754sp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0); -+} -+ -+static inline int ieee754dp_eq(ieee754dp x, ieee754dp y) -+{ -+ return ieee754dp_cmp(x, y, IEEE754_CEQ, 0); -+} -+ -+static inline int ieee754dp_ne(ieee754dp x, ieee754dp y) -+{ -+ return ieee754dp_cmp(x, y, -+ IEEE754_CLT | IEEE754_CGT | IEEE754_CUN, 0); -+} -+ -+static inline int ieee754dp_lt(ieee754dp x, ieee754dp y) -+{ -+ return ieee754dp_cmp(x, y, IEEE754_CLT, 0); -+} -+ -+static inline int ieee754dp_le(ieee754dp x, ieee754dp y) -+{ -+ return ieee754dp_cmp(x, y, IEEE754_CLT | IEEE754_CEQ, 0); -+} -+ -+static inline int ieee754dp_gt(ieee754dp x, ieee754dp y) -+{ -+ return ieee754dp_cmp(x, y, IEEE754_CGT, 0); -+} -+ -+static inline int ieee754dp_ge(ieee754dp x, ieee754dp y) -+{ -+ return ieee754dp_cmp(x, y, IEEE754_CGT | IEEE754_CEQ, 0); -+} -+ -+ -+/* -+ * Like strtod -+ */ -+ieee754dp ieee754dp_fstr(const char *s, char **endp); -+char *ieee754dp_tstr(ieee754dp x, int prec, int fmt, int af); -+ -+ -+/* -+ * The control status register -+ */ -+struct _ieee754_csr { -+#ifdef __BIG_ENDIAN -+ unsigned pad0:12; -+ unsigned cx:7; /* exceptions this operation */ -+ unsigned nod:1; /* set 1 for no denormalised numbers */ -+ unsigned mx:5; /* exception enable mask */ -+ unsigned sx:5; /* exceptions total */ -+ unsigned rm:2; /* current rounding mode */ -+#endif -+#ifdef __LITTLE_ENDIAN -+ unsigned rm:2; /* current rounding mode */ -+ unsigned sx:5; /* exceptions total */ -+ unsigned mx:5; /* exception enable mask */ -+ unsigned nod:1; /* set 1 for no denormalised numbers */ -+ unsigned cx:7; /* exceptions this operation */ -+ unsigned pad0:12; -+#endif -+}; -+#define ieee754_csr (*(struct _ieee754_csr *)(¤t->thread.fpu.fpcsr)) -+ -+static inline unsigned ieee754_getrm(void) -+{ -+ return (ieee754_csr.rm); -+} -+static inline unsigned ieee754_setrm(unsigned rm) -+{ -+ return (ieee754_csr.rm = rm); -+} -+ -+/* -+ * get current exceptions -+ */ -+static inline unsigned ieee754_getcx(void) -+{ -+ return (ieee754_csr.cx); -+} -+ -+/* test for current exception condition -+ */ -+static inline int ieee754_cxtest(unsigned n) -+{ -+ return (ieee754_csr.cx & n); -+} -+ -+/* -+ * get sticky exceptions -+ */ -+static inline unsigned ieee754_getsx(void) -+{ -+ return (ieee754_csr.sx); -+} -+ -+/* clear sticky conditions -+*/ -+static inline unsigned ieee754_clrsx(void) -+{ -+ return (ieee754_csr.sx = 0); -+} -+ -+/* test for sticky exception condition -+ */ -+static inline int ieee754_sxtest(unsigned n) -+{ -+ return (ieee754_csr.sx & n); -+} -+ -+/* debugging */ -+ieee754sp ieee754sp_dump(char *s, ieee754sp x); -+ieee754dp ieee754dp_dump(char *s, ieee754dp x); -+ -+#define IEEE754_SPCVAL_PZERO 0 -+#define IEEE754_SPCVAL_NZERO 1 -+#define IEEE754_SPCVAL_PONE 2 -+#define IEEE754_SPCVAL_NONE 3 -+#define IEEE754_SPCVAL_PTEN 4 -+#define IEEE754_SPCVAL_NTEN 5 -+#define IEEE754_SPCVAL_PINFINITY 6 -+#define IEEE754_SPCVAL_NINFINITY 7 -+#define IEEE754_SPCVAL_INDEF 8 -+#define IEEE754_SPCVAL_PMAX 9 /* +max norm */ -+#define IEEE754_SPCVAL_NMAX 10 /* -max norm */ -+#define IEEE754_SPCVAL_PMIN 11 /* +min norm */ -+#define IEEE754_SPCVAL_NMIN 12 /* +min norm */ -+#define IEEE754_SPCVAL_PMIND 13 /* +min denorm */ -+#define IEEE754_SPCVAL_NMIND 14 /* +min denorm */ -+#define IEEE754_SPCVAL_P1E31 15 /* + 1.0e31 */ -+#define IEEE754_SPCVAL_P1E63 16 /* + 1.0e63 */ -+ -+extern const struct ieee754dp_konst __ieee754dp_spcvals[]; -+extern const struct ieee754sp_konst __ieee754sp_spcvals[]; -+#define ieee754dp_spcvals ((const ieee754dp *)__ieee754dp_spcvals) -+#define ieee754sp_spcvals ((const ieee754sp *)__ieee754sp_spcvals) -+ -+/* -+ * Return infinity with given sign -+ */ -+#define ieee754dp_inf(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) -+#define ieee754dp_zero(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) -+#define ieee754dp_one(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) -+#define ieee754dp_ten(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) -+#define ieee754dp_indef() (ieee754dp_spcvals[IEEE754_SPCVAL_INDEF]) -+#define ieee754dp_max(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) -+#define ieee754dp_min(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) -+#define ieee754dp_mind(sn) (ieee754dp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) -+#define ieee754dp_1e31() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E31]) -+#define ieee754dp_1e63() (ieee754dp_spcvals[IEEE754_SPCVAL_P1E63]) -+ -+#define ieee754sp_inf(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PINFINITY+(sn)]) -+#define ieee754sp_zero(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PZERO+(sn)]) -+#define ieee754sp_one(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PONE+(sn)]) -+#define ieee754sp_ten(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PTEN+(sn)]) -+#define ieee754sp_indef() (ieee754sp_spcvals[IEEE754_SPCVAL_INDEF]) -+#define ieee754sp_max(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMAX+(sn)]) -+#define ieee754sp_min(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIN+(sn)]) -+#define ieee754sp_mind(sn) (ieee754sp_spcvals[IEEE754_SPCVAL_PMIND+(sn)]) -+#define ieee754sp_1e31() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E31]) -+#define ieee754sp_1e63() (ieee754sp_spcvals[IEEE754_SPCVAL_P1E63]) -+ -+/* -+ * Indefinite integer value -+ */ -+#define ieee754si_indef() INT_MAX -+#ifdef LONG_LONG_MAX -+#define ieee754di_indef() LONG_LONG_MAX -+#else -+#define ieee754di_indef() ((s64)(~0ULL>>1)) -+#endif -+ -+/* IEEE exception context, passed to handler */ -+struct ieee754xctx { -+ const char *op; /* operation name */ -+ int rt; /* result type */ -+ union { -+ ieee754sp sp; /* single precision */ -+ ieee754dp dp; /* double precision */ -+#ifdef IEEE854_XP -+ ieee754xp xp; /* extended precision */ -+#endif -+ int si; /* standard signed integer (32bits) */ -+ s64 di; /* extended signed integer (64bits) */ -+ } rv; /* default result format implied by op */ -+ va_list ap; -+}; -+ -+/* result types for xctx.rt */ -+#define IEEE754_RT_SP 0 -+#define IEEE754_RT_DP 1 -+#define IEEE754_RT_XP 2 -+#define IEEE754_RT_SI 3 -+#define IEEE754_RT_DI 4 -+ -+extern void ieee754_xcpt(struct ieee754xctx *xcp); -+ -+/* compat */ -+#define ieee754dp_fix(x) ieee754dp_tint(x) -+#define ieee754sp_fix(x) ieee754sp_tint(x) -+ -+#endif /* __ARCH_MIPS_MATH_EMU_IEEE754_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754int.h linux-3.4.113/arch/nds32/math-emu/ieee754int.h ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754int.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754int.h 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,165 @@ -+/* -+ * IEEE754 floating point -+ * common internal header file -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+ -+#include "ieee754.h" -+ -+#define DP_EBIAS 1023 -+#define DP_EMIN (-1022) -+#define DP_EMAX 1023 -+#define DP_MBITS 52 -+ -+#define SP_EBIAS 127 -+#define SP_EMIN (-126) -+#define SP_EMAX 127 -+#define SP_MBITS 23 -+ -+#define DP_MBIT(x) ((u64)1 << (x)) -+#define DP_HIDDEN_BIT DP_MBIT(DP_MBITS) -+#define DP_SIGN_BIT DP_MBIT(63) -+ -+#define SP_MBIT(x) ((u32)1 << (x)) -+#define SP_HIDDEN_BIT SP_MBIT(SP_MBITS) -+#define SP_SIGN_BIT SP_MBIT(31) -+ -+ -+#define SPSIGN(sp) (sp.parts.sign) -+#define SPBEXP(sp) (sp.parts.bexp) -+#define SPMANT(sp) (sp.parts.mant) -+ -+#define DPSIGN(dp) (dp.parts.sign) -+#define DPBEXP(dp) (dp.parts.bexp) -+#define DPMANT(dp) (dp.parts.mant) -+ -+#define CLPAIR(x, y) ((x)*6+(y)) -+ -+#define CLEARCX \ -+ (ieee754_csr.cx = 0) -+ -+#define SETCX(x) \ -+ (ieee754_csr.cx |= (x), ieee754_csr.sx |= (x)) -+ -+#define SETANDTESTCX(x) \ -+ (SETCX(x), ieee754_csr.mx & (x)) -+ -+#define TSTX() \ -+ (ieee754_csr.cx & ieee754_csr.mx) -+ -+ -+#define COMPXSP \ -+ unsigned xm; int xe; int xs; int xc -+ -+#define COMPYSP \ -+ unsigned ym; int ye; int ys; int yc -+ -+#define EXPLODESP(v, vc, vs, ve, vm) \ -+{\ -+ vs = SPSIGN(v);\ -+ ve = SPBEXP(v);\ -+ vm = SPMANT(v);\ -+ if(ve == SP_EMAX+1+SP_EBIAS){\ -+ if(vm == 0)\ -+ vc = IEEE754_CLASS_INF;\ -+ else if(vm & SP_MBIT(SP_MBITS-1)) \ -+ vc = IEEE754_CLASS_SNAN;\ -+ else \ -+ vc = IEEE754_CLASS_QNAN;\ -+ } else if(ve == SP_EMIN-1+SP_EBIAS) {\ -+ if(vm) {\ -+ ve = SP_EMIN;\ -+ vc = IEEE754_CLASS_DNORM;\ -+ } else\ -+ vc = IEEE754_CLASS_ZERO;\ -+ } else {\ -+ ve -= SP_EBIAS;\ -+ vm |= SP_HIDDEN_BIT;\ -+ vc = IEEE754_CLASS_NORM;\ -+ }\ -+} -+#define EXPLODEXSP EXPLODESP(x, xc, xs, xe, xm) -+#define EXPLODEYSP EXPLODESP(y, yc, ys, ye, ym) -+ -+ -+#define COMPXDP \ -+u64 xm; int xe; int xs; int xc -+ -+#define COMPYDP \ -+u64 ym; int ye; int ys; int yc -+ -+#define EXPLODEDP(v, vc, vs, ve, vm) \ -+{\ -+ vm = DPMANT(v);\ -+ vs = DPSIGN(v);\ -+ ve = DPBEXP(v);\ -+ if(ve == DP_EMAX+1+DP_EBIAS){\ -+ if(vm == 0)\ -+ vc = IEEE754_CLASS_INF;\ -+ else if(vm & DP_MBIT(DP_MBITS-1)) \ -+ vc = IEEE754_CLASS_SNAN;\ -+ else \ -+ vc = IEEE754_CLASS_QNAN;\ -+ } else if(ve == DP_EMIN-1+DP_EBIAS) {\ -+ if(vm) {\ -+ ve = DP_EMIN;\ -+ vc = IEEE754_CLASS_DNORM;\ -+ } else\ -+ vc = IEEE754_CLASS_ZERO;\ -+ } else {\ -+ ve -= DP_EBIAS;\ -+ vm |= DP_HIDDEN_BIT;\ -+ vc = IEEE754_CLASS_NORM;\ -+ }\ -+} -+#define EXPLODEXDP EXPLODEDP(x, xc, xs, xe, xm) -+#define EXPLODEYDP EXPLODEDP(y, yc, ys, ye, ym) -+ -+#define FLUSHDP(v, vc, vs, ve, vm) \ -+ if(vc==IEEE754_CLASS_DNORM) {\ -+ if(ieee754_csr.nod) {\ -+ SETCX(IEEE754_INEXACT);\ -+ vc = IEEE754_CLASS_ZERO;\ -+ ve = DP_EMIN-1+DP_EBIAS;\ -+ vm = 0;\ -+ v = ieee754dp_zero(vs);\ -+ }\ -+ } -+ -+#define FLUSHSP(v, vc, vs, ve, vm) \ -+ if(vc==IEEE754_CLASS_DNORM) {\ -+ if(ieee754_csr.nod) {\ -+ SETCX(IEEE754_INEXACT);\ -+ vc = IEEE754_CLASS_ZERO;\ -+ ve = SP_EMIN-1+SP_EBIAS;\ -+ vm = 0;\ -+ v = ieee754sp_zero(vs);\ -+ }\ -+ } -+ -+#define FLUSHXDP FLUSHDP(x, xc, xs, xe, xm) -+#define FLUSHYDP FLUSHDP(y, yc, ys, ye, ym) -+#define FLUSHXSP FLUSHSP(x, xc, xs, xe, xm) -+#define FLUSHYSP FLUSHSP(y, yc, ys, ye, ym) -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754m.c linux-3.4.113/arch/nds32/math-emu/ieee754m.c ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754m.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754m.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,55 @@ -+/* -+ * floor, trunc, ceil -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754.h" -+ -+ieee754dp ieee754dp_floor(ieee754dp x) -+{ -+ ieee754dp i; -+ -+ if (ieee754dp_lt(ieee754dp_modf(x, &i), ieee754dp_zero(0))) -+ return ieee754dp_sub(i, ieee754dp_one(0)); -+ else -+ return i; -+} -+ -+ieee754dp ieee754dp_ceil(ieee754dp x) -+{ -+ ieee754dp i; -+ -+ if (ieee754dp_gt(ieee754dp_modf(x, &i), ieee754dp_zero(0))) -+ return ieee754dp_add(i, ieee754dp_one(0)); -+ else -+ return i; -+} -+ -+ieee754dp ieee754dp_trunc(ieee754dp x) -+{ -+ ieee754dp i; -+ -+ (void)ieee754dp_modf(x, &i); -+ return i; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754sp.c linux-3.4.113/arch/nds32/math-emu/ieee754sp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754sp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754sp.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,239 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+int ieee754sp_class(ieee754sp x) -+{ -+ COMPXSP; -+ EXPLODEXSP; -+ return xc; -+} -+ -+int ieee754sp_isnan(ieee754sp x) -+{ -+ return ieee754sp_class(x) >= IEEE754_CLASS_SNAN; -+} -+ -+int ieee754sp_issnan(ieee754sp x) -+{ -+ assert(ieee754sp_isnan(x)); -+ return (SPMANT(x) & SP_MBIT(SP_MBITS - 1)); -+} -+ -+ieee754sp ieee754sp_xcpt(ieee754sp r, const char *op, ...) -+{ -+ struct ieee754xctx ax; -+ -+ if (!TSTX()) -+ return r; -+ -+ ax.op = op; -+ ax.rt = IEEE754_RT_SP; -+ ax.rv.sp = r; -+ va_start(ax.ap, op); -+ ieee754_xcpt(&ax); -+ va_end(ax.ap); -+ return ax.rv.sp; -+} -+ -+ieee754sp ieee754sp_nanxcpt(ieee754sp r, const char *op, ...) -+{ -+ struct ieee754xctx ax; -+ -+ assert(ieee754sp_isnan(r)); -+ -+ if (!ieee754sp_issnan(r)) /* QNAN does not cause invalid op !! */ -+ return r; -+ -+ if (!SETANDTESTCX(IEEE754_INVALID_OPERATION)) { -+ /* not enabled convert to a quiet NaN */ -+ SPMANT(r) &= (~SP_MBIT(SP_MBITS - 1)); -+ if (ieee754sp_isnan(r)) -+ return r; -+ else -+ return ieee754sp_indef(); -+ } -+ -+ ax.op = op; -+ ax.rt = 0; -+ ax.rv.sp = r; -+ va_start(ax.ap, op); -+ ieee754_xcpt(&ax); -+ va_end(ax.ap); -+ return ax.rv.sp; -+} -+ -+ieee754sp ieee754sp_bestnan(ieee754sp x, ieee754sp y) -+{ -+ assert(ieee754sp_isnan(x)); -+ assert(ieee754sp_isnan(y)); -+ -+ if (SPMANT(x) > SPMANT(y)) -+ return x; -+ else -+ return y; -+} -+ -+static unsigned get_rounding(int sn, unsigned xm) -+{ -+ /* inexact must round of 3 bits -+ */ -+ if (xm & (SP_MBIT(3) - 1)) { -+ switch (ieee754_csr.rm) { -+ case IEEE754_RZ: -+ break; -+ case IEEE754_RN: -+ xm += 0x3 + ((xm >> 3) & 1); -+ /* xm += (xm&0x8)?0x4:0x3 */ -+ break; -+ case IEEE754_RU: /* toward +Infinity */ -+ if (!sn) /* ?? */ -+ xm += 0x8; -+ break; -+ case IEEE754_RD: /* toward -Infinity */ -+ if (sn) /* ?? */ -+ xm += 0x8; -+ break; -+ } -+ } -+ return xm; -+} -+ -+/* generate a normal/denormal number with over,under handling -+ * sn is sign -+ * xe is an unbiased exponent -+ * xm is 3bit extended precision value. -+ */ -+ieee754sp ieee754sp_format(int sn, int xe, unsigned xm) -+{ -+ assert(xm); /* we don't gen exact zeros (probably should) */ -+ -+ assert((xm >> (SP_MBITS + 1 + 3)) == 0); /* no execess */ -+ assert(xm & (SP_HIDDEN_BIT << 3)); -+ -+ if (xe < SP_EMIN) { -+ /* strip lower bits */ -+ int es = SP_EMIN - xe; -+ -+ if (ieee754_csr.nod) { -+ SETCX(IEEE754_UNDERFLOW); -+ SETCX(IEEE754_INEXACT); -+ -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ return ieee754sp_zero(sn); -+ case IEEE754_RZ: -+ return ieee754sp_zero(sn); -+ case IEEE754_RU: /* toward +Infinity */ -+ if (sn == 0) -+ return ieee754sp_min(0); -+ else -+ return ieee754sp_zero(1); -+ case IEEE754_RD: /* toward -Infinity */ -+ if (sn == 0) -+ return ieee754sp_zero(0); -+ else -+ return ieee754sp_min(1); -+ } -+ } -+ -+ if (xe == SP_EMIN - 1 -+ && get_rounding(sn, xm) >> (SP_MBITS + 1 + 3)) { -+ /* Not tiny after rounding */ -+ SETCX(IEEE754_INEXACT); -+ xm = get_rounding(sn, xm); -+ xm >>= 1; -+ /* Clear grs bits */ -+ xm &= ~(SP_MBIT(3) - 1); -+ xe++; -+ } else { -+ /* sticky right shift es bits -+ */ -+ SPXSRSXn(es); -+ assert((xm & (SP_HIDDEN_BIT << 3)) == 0); -+ assert(xe == SP_EMIN); -+ } -+ } -+ if (xm & (SP_MBIT(3) - 1)) { -+ SETCX(IEEE754_INEXACT); -+ if ((xm & (SP_HIDDEN_BIT << 3)) == 0) { -+ SETCX(IEEE754_UNDERFLOW); -+ } -+ -+ /* inexact must round of 3 bits -+ */ -+ xm = get_rounding(sn, xm); -+ /* adjust exponent for rounding add overflowing -+ */ -+ if (xm >> (SP_MBITS + 1 + 3)) { -+ /* add causes mantissa overflow */ -+ xm >>= 1; -+ xe++; -+ } -+ } -+ /* strip grs bits */ -+ xm >>= 3; -+ -+ assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ -+ assert(xe >= SP_EMIN); -+ -+ if (xe > SP_EMAX) { -+ SETCX(IEEE754_OVERFLOW); -+ SETCX(IEEE754_INEXACT); -+ /* -O can be table indexed by (rm,sn) */ -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ return ieee754sp_inf(sn); -+ case IEEE754_RZ: -+ return ieee754sp_max(sn); -+ case IEEE754_RU: /* toward +Infinity */ -+ if (sn == 0) -+ return ieee754sp_inf(0); -+ else -+ return ieee754sp_max(1); -+ case IEEE754_RD: /* toward -Infinity */ -+ if (sn == 0) -+ return ieee754sp_max(0); -+ else -+ return ieee754sp_inf(1); -+ } -+ } -+ /* gen norm/denorm/zero */ -+ -+ if ((xm & SP_HIDDEN_BIT) == 0) { -+ /* we underflow (tiny/zero) */ -+ assert(xe == SP_EMIN); -+ if (ieee754_csr.mx & IEEE754_UNDERFLOW) -+ SETCX(IEEE754_UNDERFLOW); -+ return buildsp(sn, SP_EMIN - 1 + SP_EBIAS, xm); -+ } else { -+ assert((xm >> (SP_MBITS + 1)) == 0); /* no execess */ -+ assert(xm & SP_HIDDEN_BIT); -+ -+ return buildsp(sn, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754sp.h linux-3.4.113/arch/nds32/math-emu/ieee754sp.h ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754sp.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754sp.h 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,89 @@ -+/* -+ * IEEE754 floating point -+ * double precision internal header file -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+ -+#include "ieee754int.h" -+ -+#define assert(expr) ((void)0) -+ -+/* 3bit extended single precision sticky right shift */ -+#define SPXSRSXn(rs) \ -+ (xe += rs, \ -+ xm = (rs > (SP_MBITS+3))?1:((xm) >> (rs)) | ((xm) << (32-(rs)) != 0)) -+ -+#define SPXSRSX1() \ -+ (xe++, (xm = (xm >> 1) | (xm & 1))) -+ -+#define SPXSRSYn(rs) \ -+ (ye+=rs, \ -+ ym = (rs > (SP_MBITS+3))?1:((ym) >> (rs)) | ((ym) << (32-(rs)) != 0)) -+ -+#define SPXSRSY1() \ -+ (ye++, (ym = (ym >> 1) | (ym & 1))) -+ -+/* convert denormal to normalized with extended exponent */ -+#define SPDNORMx(m,e) \ -+ while( (m >> SP_MBITS) == 0) { m <<= 1; e--; } -+#define SPDNORMX SPDNORMx(xm, xe) -+#define SPDNORMY SPDNORMx(ym, ye) -+ -+static inline ieee754sp buildsp(int s, int bx, unsigned m) -+{ -+ ieee754sp r; -+ -+ assert((s) == 0 || (s) == 1); -+ assert((bx) >= SP_EMIN - 1 + SP_EBIAS -+ && (bx) <= SP_EMAX + 1 + SP_EBIAS); -+ assert(((m) >> SP_MBITS) == 0); -+ -+ r.parts.sign = s; -+ r.parts.bexp = bx; -+ r.parts.mant = m; -+ -+ return r; -+} -+ -+extern int ieee754sp_isnan(ieee754sp); -+extern int ieee754sp_issnan(ieee754sp); -+extern int ieee754si_xcpt(int, const char *, ...); -+extern s64 ieee754di_xcpt(s64, const char *, ...); -+extern ieee754sp ieee754sp_xcpt(ieee754sp, const char *, ...); -+extern ieee754sp ieee754sp_nanxcpt(ieee754sp, const char *, ...); -+extern ieee754sp ieee754sp_bestnan(ieee754sp, ieee754sp); -+extern ieee754sp ieee754sp_format(int, int, unsigned); -+ -+ -+#define SPNORMRET2(s, e, m, name, a0, a1) \ -+{ \ -+ ieee754sp V = ieee754sp_format(s, e, m); \ -+ if(TSTX()) \ -+ return ieee754sp_xcpt(V, name, a0, a1); \ -+ else \ -+ return V; \ -+} -+ -+#define SPNORMRET1(s, e, m, name, a0) SPNORMRET2(s, e, m, name, a0, a0) -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/ieee754xcpt.c linux-3.4.113/arch/nds32/math-emu/ieee754xcpt.c ---- linux-3.4.113.orig/arch/nds32/math-emu/ieee754xcpt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/ieee754xcpt.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,48 @@ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope 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. -+ * -+ * ######################################################################## -+ */ -+ -+/************************************************************************** -+ * Nov 7, 2000 -+ * Added preprocessor hacks to map to Linux kernel diagnostics. -+ * -+ * Kevin D. Kissell, kevink@mips.com and Carsten Langgaard, carstenl@mips.com -+ * Copyright (C) 2000 MIPS Technologies, Inc. All rights reserved. -+ *************************************************************************/ -+ -+#include -+#include "ieee754.h" -+ -+/* -+ * Very naff exception handler (you can plug in your own and -+ * override this). -+ */ -+ -+static const char *const rtnames[] = { -+ "sp", "dp", "xp", "si", "di" -+}; -+ -+void ieee754_xcpt(struct ieee754xctx *xcp) -+{ -+ printk(KERN_DEBUG "floating point exception in \"%s\", type=%s\n", -+ xcp->op, rtnames[xcp->rt]); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/insn.h linux-3.4.113/arch/nds32/math-emu/insn.h ---- linux-3.4.113.orig/arch/nds32/math-emu/insn.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/insn.h 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,101 @@ -+#ifndef _ASM_INST_H -+#define _ASM_INST_H -+ -+#define cop0_op 0x35 -+ -+/* -+ * COP0 field of opcodes. -+ */ -+#define fs1_op 0x0 -+#define fs2_op 0x4 -+#define fd1_op 0x8 -+#define fd2_op 0xc -+ -+/* -+ * FS1 opcode. -+ */ -+enum fs1 { -+ fadds_op, fsubs_op, fcpynss_op, fcpyss_op, -+ fmadds_op, fmsubs_op, fcmovns_op, fcmovzs_op, -+ fnmadds_op, fnmsubs_op, -+ fmuls_op = 0xc, fdivs_op, -+ fs1_f2op_op = 0xf -+}; -+ -+/* -+ * FS1/F2OP opcode. -+ */ -+enum fs1_f2 { -+ fs2d_op, fsqrts_op, fabss_op = 0x5, -+ fui2s_op = 0x8, fsi2s_op = 0xc, -+ fs2ui_op = 0x10, fs2ui_z_op = 0x14, -+ fs2si_op = 0x18, fs2si_z_op = 0x1c -+}; -+ -+/* -+ * FS2 opcode. -+ */ -+enum fs2 { -+ fcmpeqs_op, fcmpeqs_e_op, fcmplts_op, fcmplts_e_op, -+ fcmples_op, fcmples_e_op, fcmpuns_op, fcmpuns_e_op -+}; -+ -+/* -+ * FD1 opcode. -+ */ -+enum fd1 { -+ faddd_op, fsubd_op, fcpynsd_op, fcpysd_op, -+ fmaddd_op, fmsubd_op, fcmovnd_op, fcmovzd_op, -+ fnmaddd_op, fnmsubd_op, -+ fmuld_op = 0xc, fdivd_op, fd1_f2op_op = 0xf -+}; -+ -+/* -+ * FD1/F2OP opcode. -+ */ -+enum fd1_f2 { -+ fd2s_op, fsqrtd_op, fabsd_op = 0x5, -+ fui2d_op = 0x8, fsi2d_op = 0xc, -+ fd2ui_op = 0x10, fd2ui_z_op = 0x14, -+ fd2si_op = 0x18, fd2si_z_op = 0x1c -+}; -+ -+/* -+ * FD2 opcode. -+ */ -+enum fd2 { -+ fcmpeqd_op, fcmpeqd_e_op, fcmpltd_op, fcmpltd_e_op, -+ fcmpled_op, fcmpled_e_op, fcmpund_op, fcmpund_e_op -+}; -+ -+ -+#define NDS32Insn(x) x -+ -+#define I_OPCODE_off 25 -+#define NDS32Insn_OPCODE(x) (NDS32Insn(x) >> I_OPCODE_off) -+ -+#define I_OPCODE_offRt 20 -+#define I_OPCODE_mskRt (0x1fUL << I_OPCODE_offRt) -+#define NDS32Insn_OPCODE_Rt(x) ((NDS32Insn(x) & I_OPCODE_mskRt) >> I_OPCODE_offRt) -+ -+#define I_OPCODE_offRa 15 -+#define I_OPCODE_mskRa (0x1fUL << I_OPCODE_offRa) -+#define NDS32Insn_OPCODE_Ra(x) ((NDS32Insn(x) & I_OPCODE_mskRa) >> I_OPCODE_offRa) -+ -+#define I_OPCODE_offRb 10 -+#define I_OPCODE_mskRb (0x1fUL << I_OPCODE_offRb) -+#define NDS32Insn_OPCODE_Rb(x) ((NDS32Insn(x) & I_OPCODE_mskRb) >> I_OPCODE_offRb) -+ -+#define I_OPCODE_offbit1014 10 -+#define I_OPCODE_mskbit1014 (0x1fUL << I_OPCODE_offbit1014) -+#define NDS32Insn_OPCODE_BIT1014(x) ((NDS32Insn(x) & I_OPCODE_mskbit1014) >> I_OPCODE_offbit1014) -+ -+#define I_OPCODE_offbit69 6 -+#define I_OPCODE_mskbit69 (0xfUL << I_OPCODE_offbit69) -+#define NDS32Insn_OPCODE_BIT69(x) ((NDS32Insn(x) & I_OPCODE_mskbit69) >> I_OPCODE_offbit69) -+ -+#define I_OPCODE_offCOP0 0 -+#define I_OPCODE_mskCOP0 (0x3fUL << I_OPCODE_offCOP0) -+#define NDS32Insn_OPCODE_COP0(x) ((NDS32Insn(x) & I_OPCODE_mskCOP0) >> I_OPCODE_offCOP0) -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/Makefile linux-3.4.113/arch/nds32/math-emu/Makefile ---- linux-3.4.113.orig/arch/nds32/math-emu/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/Makefile 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,13 @@ -+# -+# Makefile for the Linux/nds32 kernel FPU emulation. -+# -+ -+obj-y := fpuemu.o ieee754m.o ieee754d.o ieee754dp.o ieee754sp.o ieee754.o \ -+ ieee754xcpt.o dp_frexp.o dp_modf.o dp_div.o dp_mul.o dp_sub.o \ -+ dp_add.o dp_fsp.o dp_cmp.o dp_logb.o dp_scalb.o dp_simple.o \ -+ dp_tint.o dp_fint.o dp_tlong.o dp_flong.o sp_frexp.o sp_modf.o \ -+ sp_div.o sp_mul.o sp_sub.o sp_add.o sp_fdp.o sp_cmp.o sp_logb.o \ -+ sp_scalb.o sp_simple.o sp_tint.o sp_fint.o sp_tlong.o sp_flong.o \ -+ dp_sqrt.o sp_sqrt.o -+ -+EXTRA_CFLAGS += -Werror -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_add.c linux-3.4.113/arch/nds32/math-emu/sp_add.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_add.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_add.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,173 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_add(ieee754sp x, ieee754sp y) -+{ -+ COMPXSP; -+ COMPYSP; -+ -+ EXPLODEXSP; -+ EXPLODEYSP; -+ -+ CLEARCX; -+ -+ FLUSHXSP; -+ FLUSHYSP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "add", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ if (xs == ys) -+ return x; -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_xcpt(ieee754sp_indef(), "add", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ return x; -+ -+ /* Zero handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ if (xs == ys) -+ return x; -+ else -+ return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ return x; -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ SPDNORMX; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ SPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ SPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ assert(xm & SP_HIDDEN_BIT); -+ assert(ym & SP_HIDDEN_BIT); -+ -+ /* provide guard,round and stick bit space */ -+ xm <<= 3; -+ ym <<= 3; -+ -+ if (xe > ye) { -+ /* have to shift y fraction right to align -+ */ -+ int s = xe - ye; -+ SPXSRSYn(s); -+ } else if (ye > xe) { -+ /* have to shift x fraction right to align -+ */ -+ int s = ye - xe; -+ SPXSRSXn(s); -+ } -+ assert(xe == ye); -+ assert(xe <= SP_EMAX); -+ -+ if (xs == ys) { -+ /* generate 28 bit result of adding two 27 bit numbers -+ * leaving result in xm,xs,xe -+ */ -+ xm = xm + ym; -+ xe = xe; -+ xs = xs; -+ -+ if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */ -+ SPXSRSX1(); -+ } -+ } else { -+ if (xm >= ym) { -+ xm = xm - ym; -+ xe = xe; -+ xs = xs; -+ } else { -+ xm = ym - xm; -+ xe = xe; -+ xs = ys; -+ } -+ if (xm == 0) -+ return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD); -+ -+ /* normalize in extended single precision */ -+ while ((xm >> (SP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ -+ } -+ SPNORMRET2(xs, xe, xm, "add", x, y); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_cmp.c linux-3.4.113/arch/nds32/math-emu/sp_cmp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_cmp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_cmp.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,66 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+int ieee754sp_cmp(ieee754sp x, ieee754sp y, int cmp, int sig) -+{ -+ COMPXSP; -+ COMPYSP; -+ -+ EXPLODEXSP; -+ EXPLODEYSP; -+ FLUSHXSP; -+ FLUSHYSP; -+ CLEARCX; /* Even clear inexact flag here */ -+ -+ if (ieee754sp_isnan(x) || ieee754sp_isnan(y)) { -+ if (sig || xc == IEEE754_CLASS_SNAN || yc == IEEE754_CLASS_SNAN) -+ SETCX(IEEE754_INVALID_OPERATION); -+ if (cmp & IEEE754_CUN) -+ return 1; -+ if (cmp & (IEEE754_CLT | IEEE754_CGT)) { -+ if (sig && SETANDTESTCX(IEEE754_INVALID_OPERATION)) -+ return ieee754si_xcpt(0, "fcmpf", x); -+ } -+ return 0; -+ } else { -+ int vx = x.bits; -+ int vy = y.bits; -+ -+ if (vx < 0) -+ vx = -vx ^ SP_SIGN_BIT; -+ if (vy < 0) -+ vy = -vy ^ SP_SIGN_BIT; -+ -+ if (vx < vy) -+ return (cmp & IEEE754_CLT) != 0; -+ else if (vx == vy) -+ return (cmp & IEEE754_CEQ) != 0; -+ else -+ return (cmp & IEEE754_CGT) != 0; -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_div.c linux-3.4.113/arch/nds32/math-emu/sp_div.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_div.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_div.c 2016-12-01 20:59:24.364613214 +0100 -@@ -0,0 +1,155 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_div(ieee754sp x, ieee754sp y) -+{ -+ COMPXSP; -+ COMPYSP; -+ -+ EXPLODEXSP; -+ EXPLODEYSP; -+ -+ CLEARCX; -+ -+ FLUSHXSP; -+ FLUSHYSP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ return ieee754sp_zero(xs ^ ys); -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ return ieee754sp_inf(xs ^ ys); -+ -+ /* Zero handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_xcpt(ieee754sp_indef(), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ SETCX(IEEE754_ZERO_DIVIDE); -+ return ieee754sp_xcpt(ieee754sp_inf(xs ^ ys), "div", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ return ieee754sp_zero(xs == ys ? 0 : 1); -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ SPDNORMX; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ SPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ SPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ assert(xm & SP_HIDDEN_BIT); -+ assert(ym & SP_HIDDEN_BIT); -+ -+ /* provide rounding space */ -+ xm <<= 3; -+ ym <<= 3; -+ -+ { -+ /* now the dirty work */ -+ -+ unsigned rm = 0; -+ int re = xe - ye; -+ unsigned bm; -+ -+ for (bm = SP_MBIT(SP_MBITS + 2); bm; bm >>= 1) { -+ if (xm >= ym) { -+ xm -= ym; -+ rm |= bm; -+ if (xm == 0) -+ break; -+ } -+ xm <<= 1; -+ } -+ rm <<= 1; -+ if (xm) -+ rm |= 1; /* have remainder, set sticky */ -+ -+ assert(rm); -+ -+ /* normalise rm to rounding precision ? -+ */ -+ while ((rm >> (SP_MBITS + 3)) == 0) { -+ rm <<= 1; -+ re--; -+ } -+ -+ SPNORMRET2(xs == ys ? 0 : 1, re, rm, "div", x, y); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_fdp.c linux-3.4.113/arch/nds32/math-emu/sp_fdp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_fdp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_fdp.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,76 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_fdp(ieee754dp x) -+{ -+ COMPXDP; -+ ieee754sp nan; -+ -+ EXPLODEXDP; -+ -+ CLEARCX; -+ -+ FLUSHXDP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "fdp"); -+ case IEEE754_CLASS_QNAN: -+ nan = buildsp(xs, SP_EMAX + 1 + SP_EBIAS, (u32) -+ (xm >> (DP_MBITS - SP_MBITS))); -+ if (!ieee754sp_isnan(nan)) -+ nan = ieee754sp_indef(); -+ return ieee754sp_nanxcpt(nan, "fdp", x); -+ case IEEE754_CLASS_INF: -+ return ieee754sp_inf(xs); -+ case IEEE754_CLASS_ZERO: -+ return ieee754sp_zero(xs); -+ case IEEE754_CLASS_DNORM: -+ /* can't possibly be sp representable */ -+ SETCX(IEEE754_UNDERFLOW); -+ SETCX(IEEE754_INEXACT); -+ if ((ieee754_csr.rm == IEEE754_RU && !xs) || -+ (ieee754_csr.rm == IEEE754_RD && xs)) -+ return ieee754sp_xcpt(ieee754sp_mind(xs), "fdp", x); -+ return ieee754sp_xcpt(ieee754sp_zero(xs), "fdp", x); -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ -+ { -+ u32 rm; -+ -+ /* convert from DP_MBITS to SP_MBITS+3 with sticky right shift -+ */ -+ rm = (xm >> (DP_MBITS - (SP_MBITS + 3))) | -+ ((xm << (64 - (DP_MBITS - (SP_MBITS + 3)))) != 0); -+ -+ SPNORMRET1(xs, xe, rm, "fdp", x); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_fint.c linux-3.4.113/arch/nds32/math-emu/sp_fint.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_fint.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_fint.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,78 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_fint(int x) -+{ -+ unsigned xm; -+ int xe; -+ int xs; -+ -+ CLEARCX; -+ -+ if (x == 0) -+ return ieee754sp_zero(0); -+ if (x == 1 || x == -1) -+ return ieee754sp_one(x < 0); -+ if (x == 10 || x == -10) -+ return ieee754sp_ten(x < 0); -+ -+ xs = (x < 0); -+ if (xs) { -+ if (x == (1 << 31)) -+ xm = ((unsigned)1 << 31); /* max neg can't be safely negated */ -+ else -+ xm = -x; -+ } else { -+ xm = x; -+ } -+ xe = SP_MBITS + 3; -+ -+ if (xm >> (SP_MBITS + 1 + 3)) { -+ /* shunt out overflow bits -+ */ -+ while (xm >> (SP_MBITS + 1 + 3)) { -+ SPXSRSX1(); -+ } -+ } else { -+ /* normalize in grs extended single precision -+ */ -+ while ((xm >> (SP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ } -+ SPNORMRET1(xs, xe, xm, "fint", x); -+} -+ -+ieee754sp ieee754sp_funs(unsigned int u) -+{ -+ if ((int)u < 0) -+ return ieee754sp_add(ieee754sp_1e31(), -+ ieee754sp_fint(u & ~(1 << 31))); -+ return ieee754sp_fint(u); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_flong.c linux-3.4.113/arch/nds32/math-emu/sp_flong.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_flong.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_flong.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,77 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_flong(s64 x) -+{ -+ u64 xm; /* <--- need 64-bit mantissa temp */ -+ int xe; -+ int xs; -+ -+ CLEARCX; -+ -+ if (x == 0) -+ return ieee754sp_zero(0); -+ if (x == 1 || x == -1) -+ return ieee754sp_one(x < 0); -+ if (x == 10 || x == -10) -+ return ieee754sp_ten(x < 0); -+ -+ xs = (x < 0); -+ if (xs) { -+ if (x == (1ULL << 63)) -+ xm = (1ULL << 63); /* max neg can't be safely negated */ -+ else -+ xm = -x; -+ } else { -+ xm = x; -+ } -+ xe = SP_MBITS + 3; -+ -+ if (xm >> (SP_MBITS + 1 + 3)) { -+ /* shunt out overflow bits -+ */ -+ while (xm >> (SP_MBITS + 1 + 3)) { -+ SPXSRSX1(); -+ } -+ } else { -+ /* normalize in grs extended single precision */ -+ while ((xm >> (SP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ } -+ SPNORMRET1(xs, xe, xm, "sp_flong", x); -+} -+ -+ieee754sp ieee754sp_fulong(u64 u) -+{ -+ if ((s64) u < 0) -+ return ieee754sp_add(ieee754sp_1e63(), -+ ieee754sp_flong(u & ~(1ULL << 63))); -+ return ieee754sp_flong(u); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_frexp.c linux-3.4.113/arch/nds32/math-emu/sp_frexp.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_frexp.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_frexp.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,52 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+/* close to ieeep754sp_logb -+*/ -+ieee754sp ieee754sp_frexp(ieee754sp x, int *eptr) -+{ -+ COMPXSP; -+ CLEARCX; -+ EXPLODEXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ case IEEE754_CLASS_ZERO: -+ *eptr = 0; -+ return x; -+ case IEEE754_CLASS_DNORM: -+ SPDNORMX; -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ *eptr = xe + 1; -+ return buildsp(xs, -1 + SP_EBIAS, xm & ~SP_HIDDEN_BIT); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_logb.c linux-3.4.113/arch/nds32/math-emu/sp_logb.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_logb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_logb.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,53 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_logb(ieee754sp x) -+{ -+ COMPXSP; -+ -+ CLEARCX; -+ -+ EXPLODEXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ return ieee754sp_nanxcpt(x, "logb", x); -+ case IEEE754_CLASS_QNAN: -+ return x; -+ case IEEE754_CLASS_INF: -+ return ieee754sp_inf(0); -+ case IEEE754_CLASS_ZERO: -+ return ieee754sp_inf(1); -+ case IEEE754_CLASS_DNORM: -+ SPDNORMX; -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ return ieee754sp_fint(xe); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_modf.c linux-3.4.113/arch/nds32/math-emu/sp_modf.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_modf.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_modf.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,79 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+/* modf function is always exact for a finite number -+*/ -+ieee754sp ieee754sp_modf(ieee754sp x, ieee754sp * ip) -+{ -+ COMPXSP; -+ -+ CLEARCX; -+ -+ EXPLODEXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ case IEEE754_CLASS_ZERO: -+ *ip = x; -+ return x; -+ case IEEE754_CLASS_DNORM: -+ /* far to small */ -+ *ip = ieee754sp_zero(xs); -+ return x; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ if (xe < 0) { -+ *ip = ieee754sp_zero(xs); -+ return x; -+ } -+ if (xe >= SP_MBITS) { -+ *ip = x; -+ return ieee754sp_zero(xs); -+ } -+ /* generate ipart mantissa by clearing bottom bits -+ */ -+ *ip = buildsp(xs, xe + SP_EBIAS, -+ ((xm >> (SP_MBITS - xe)) << (SP_MBITS - xe)) & -+ ~SP_HIDDEN_BIT); -+ -+ /* generate fpart mantissa by clearing top bits -+ * and normalizing (must be able to normalize) -+ */ -+ xm = (xm << (32 - (SP_MBITS - xe))) >> (32 - (SP_MBITS - xe)); -+ if (xm == 0) -+ return ieee754sp_zero(xs); -+ -+ while ((xm >> SP_MBITS) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ return buildsp(xs, xe + SP_EBIAS, xm & ~SP_HIDDEN_BIT); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_mul.c linux-3.4.113/arch/nds32/math-emu/sp_mul.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_mul.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_mul.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,168 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_mul(ieee754sp x, ieee754sp y) -+{ -+ COMPXSP; -+ COMPYSP; -+ -+ EXPLODEXSP; -+ EXPLODEYSP; -+ -+ CLEARCX; -+ -+ FLUSHXSP; -+ FLUSHYSP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "mul", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_xcpt(ieee754sp_indef(), "mul", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ return ieee754sp_inf(xs ^ ys); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ return ieee754sp_zero(xs ^ ys); -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ SPDNORMX; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ SPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ SPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ /* rm = xm * ym, re = xe+ye basicly */ -+ assert(xm & SP_HIDDEN_BIT); -+ assert(ym & SP_HIDDEN_BIT); -+ -+ { -+ int re = xe + ye; -+ int rs = xs ^ ys; -+ unsigned rm; -+ -+ /* shunt to top of word */ -+ xm <<= 32 - (SP_MBITS + 1); -+ ym <<= 32 - (SP_MBITS + 1); -+ -+ /* multiply 32bits xm,ym to give high 32bits rm with stickness -+ */ -+ { -+ unsigned short lxm = xm & 0xffff; -+ unsigned short hxm = xm >> 16; -+ unsigned short lym = ym & 0xffff; -+ unsigned short hym = ym >> 16; -+ unsigned lrm; -+ unsigned hrm; -+ -+ lrm = lxm * lym; /* 16 * 16 => 32 */ -+ hrm = hxm * hym; /* 16 * 16 => 32 */ -+ -+ { -+ unsigned t = lxm * hym; /* 16 * 16 => 32 */ -+ { -+ unsigned at = lrm + (t << 16); -+ hrm += at < lrm; -+ lrm = at; -+ } -+ hrm = hrm + (t >> 16); -+ } -+ -+ { -+ unsigned t = hxm * lym; /* 16 * 16 => 32 */ -+ { -+ unsigned at = lrm + (t << 16); -+ hrm += at < lrm; -+ lrm = at; -+ } -+ hrm = hrm + (t >> 16); -+ } -+ rm = hrm | (lrm != 0); -+ } -+ -+ /* -+ * sticky shift down to normal rounding precision -+ */ -+ if ((int)rm < 0) { -+ rm = (rm >> (32 - (SP_MBITS + 1 + 3))) | -+ ((rm << (SP_MBITS + 1 + 3)) != 0); -+ re++; -+ } else { -+ rm = (rm >> (32 - (SP_MBITS + 1 + 3 + 1))) | -+ ((rm << (SP_MBITS + 1 + 3 + 1)) != 0); -+ } -+ assert(rm & (SP_HIDDEN_BIT << 3)); -+ -+ SPNORMRET2(rs, re, rm, "mul", x, y); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_scalb.c linux-3.4.113/arch/nds32/math-emu/sp_scalb.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_scalb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_scalb.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,56 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_scalb(ieee754sp x, int n) -+{ -+ COMPXSP; -+ -+ CLEARCX; -+ -+ EXPLODEXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ return ieee754sp_nanxcpt(x, "scalb", x, n); -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ case IEEE754_CLASS_ZERO: -+ return x; -+ case IEEE754_CLASS_DNORM: -+ SPDNORMX; -+ break; -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ SPNORMRET2(xs, xe + n, xm << 3, "scalb", x, n); -+} -+ -+ieee754sp ieee754sp_ldexp(ieee754sp x, int n) -+{ -+ return ieee754sp_scalb(x, n); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_simple.c linux-3.4.113/arch/nds32/math-emu/sp_simple.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_simple.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_simple.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,87 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+int ieee754sp_finite(ieee754sp x) -+{ -+ return SPBEXP(x) != SP_EMAX + 1 + SP_EBIAS; -+} -+ -+ieee754sp ieee754sp_copysign(ieee754sp x, ieee754sp y) -+{ -+ CLEARCX; -+ SPSIGN(x) = SPSIGN(y); -+ return x; -+} -+ -+ieee754sp ieee754sp_neg(ieee754sp x) -+{ -+ COMPXSP; -+ -+ EXPLODEXSP; -+ CLEARCX; -+ FLUSHXSP; -+ -+ /* -+ * Invert the sign ALWAYS to prevent an endless recursion on -+ * pow() in libc. -+ */ -+ /* quick fix up */ -+ SPSIGN(x) ^= 1; -+ -+ if (xc == IEEE754_CLASS_SNAN) { -+ ieee754sp y = ieee754sp_indef(); -+ SETCX(IEEE754_INVALID_OPERATION); -+ SPSIGN(y) = SPSIGN(x); -+ return ieee754sp_nanxcpt(y, "neg"); -+ } -+ -+ if (ieee754sp_isnan(x)) /* but not infinity */ -+ return ieee754sp_nanxcpt(x, "neg", x); -+ return x; -+} -+ -+ieee754sp ieee754sp_abs(ieee754sp x) -+{ -+ COMPXSP; -+ -+ EXPLODEXSP; -+ CLEARCX; -+ FLUSHXSP; -+ -+ if (xc == IEEE754_CLASS_SNAN) { -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "abs"); -+ } -+ -+ if (ieee754sp_isnan(x)) /* but not infinity */ -+ return ieee754sp_nanxcpt(x, "abs", x); -+ -+ /* quick fix up */ -+ SPSIGN(x) = 0; -+ return x; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_sqrt.c linux-3.4.113/arch/nds32/math-emu/sp_sqrt.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_sqrt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_sqrt.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,116 @@ -+/* IEEE754 floating point arithmetic -+ * single precision square root -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_sqrt(ieee754sp x) -+{ -+ int ix, s, q, m, t, i; -+ unsigned int r; -+ COMPXSP; -+ -+ /* take care of Inf and NaN */ -+ -+ EXPLODEXSP; -+ CLEARCX; -+ FLUSHXSP; -+ -+ /* x == INF or NAN? */ -+ switch (xc) { -+ case IEEE754_CLASS_QNAN: -+ /* sqrt(Nan) = Nan */ -+ return ieee754sp_nanxcpt(x, "sqrt"); -+ case IEEE754_CLASS_SNAN: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); -+ case IEEE754_CLASS_ZERO: -+ /* sqrt(0) = 0 */ -+ return x; -+ case IEEE754_CLASS_INF: -+ if (xs) { -+ /* sqrt(-Inf) = Nan */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); -+ } -+ /* sqrt(+Inf) = Inf */ -+ return x; -+ case IEEE754_CLASS_DNORM: -+ case IEEE754_CLASS_NORM: -+ if (xs) { -+ /* sqrt(-x) = Nan */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sqrt"); -+ } -+ break; -+ } -+ -+ ix = x.bits; -+ -+ /* normalize x */ -+ m = (ix >> 23); -+ if (m == 0) { /* subnormal x */ -+ for (i = 0; (ix & 0x00800000) == 0; i++) -+ ix <<= 1; -+ m -= i - 1; -+ } -+ m -= 127; /* unbias exponent */ -+ ix = (ix & 0x007fffff) | 0x00800000; -+ if (m & 1) /* odd m, double x to make it even */ -+ ix += ix; -+ m >>= 1; /* m = [m/2] */ -+ -+ /* generate sqrt(x) bit by bit */ -+ ix += ix; -+ q = s = 0; /* q = sqrt(x) */ -+ r = 0x01000000; /* r = moving bit from right to left */ -+ -+ while (r != 0) { -+ t = s + r; -+ if (t <= ix) { -+ s = t + r; -+ ix -= t; -+ q += r; -+ } -+ ix += ix; -+ r >>= 1; -+ } -+ -+ if (ix != 0) { -+ SETCX(IEEE754_INEXACT); -+ switch (ieee754_csr.rm) { -+ case IEEE754_RP: -+ q += 2; -+ break; -+ case IEEE754_RN: -+ q += (q & 1); -+ break; -+ } -+ } -+ ix = (q >> 1) + 0x3f000000; -+ ix += (m << 23); -+ x.bits = ix; -+ return x; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_sub.c linux-3.4.113/arch/nds32/math-emu/sp_sub.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_sub.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_sub.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,180 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+ieee754sp ieee754sp_sub(ieee754sp x, ieee754sp y) -+{ -+ COMPXSP; -+ COMPYSP; -+ -+ EXPLODEXSP; -+ EXPLODEYSP; -+ -+ CLEARCX; -+ -+ FLUSHXSP; -+ FLUSHYSP; -+ -+ switch (CLPAIR(xc, yc)) { -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_SNAN): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_SNAN, IEEE754_CLASS_INF): -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_nanxcpt(ieee754sp_indef(), "sub", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_QNAN): -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_QNAN): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_DNORM): -+ case CLPAIR(IEEE754_CLASS_QNAN, IEEE754_CLASS_INF): -+ return x; -+ -+ /* Infinity handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_INF): -+ if (xs != ys) -+ return x; -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754sp_xcpt(ieee754sp_indef(), "sub", x, y); -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_INF): -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_INF): -+ return ieee754sp_inf(ys ^ 1); -+ -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_INF, IEEE754_CLASS_DNORM): -+ return x; -+ -+ /* Zero handling -+ */ -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_ZERO): -+ if (xs != ys) -+ return x; -+ else -+ return ieee754sp_zero(ieee754_csr.rm == IEEE754_RD); -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_ZERO): -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_ZERO): -+ return x; -+ -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_NORM): -+ case CLPAIR(IEEE754_CLASS_ZERO, IEEE754_CLASS_DNORM): -+ /* quick fix up */ -+ DPSIGN(y) ^= 1; -+ return y; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_DNORM): -+ SPDNORMX; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_DNORM): -+ SPDNORMY; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_DNORM, IEEE754_CLASS_NORM): -+ SPDNORMX; -+ break; -+ -+ case CLPAIR(IEEE754_CLASS_NORM, IEEE754_CLASS_NORM): -+ break; -+ } -+ /* flip sign of y and handle as add */ -+ ys ^= 1; -+ -+ assert(xm & SP_HIDDEN_BIT); -+ assert(ym & SP_HIDDEN_BIT); -+ -+ /* provide guard,round and stick bit space */ -+ xm <<= 3; -+ ym <<= 3; -+ -+ if (xe > ye) { -+ /* have to shift y fraction right to align -+ */ -+ int s = xe - ye; -+ SPXSRSYn(s); -+ } else if (ye > xe) { -+ /* have to shift x fraction right to align -+ */ -+ int s = ye - xe; -+ SPXSRSXn(s); -+ } -+ assert(xe == ye); -+ assert(xe <= SP_EMAX); -+ -+ if (xs == ys) { -+ /* generate 28 bit result of adding two 27 bit numbers -+ */ -+ xm = xm + ym; -+ xe = xe; -+ xs = xs; -+ -+ if (xm >> (SP_MBITS + 1 + 3)) { /* carry out */ -+ SPXSRSX1(); /* shift preserving sticky */ -+ } -+ } else { -+ if (xm >= ym) { -+ xm = xm - ym; -+ xe = xe; -+ xs = xs; -+ } else { -+ xm = ym - xm; -+ xe = xe; -+ xs = ys; -+ } -+ if (xm == 0) { -+ if (ieee754_csr.rm == IEEE754_RD) -+ return ieee754sp_zero(1); /* round negative inf. => sign = -1 */ -+ else -+ return ieee754sp_zero(0); /* other round modes => sign = 1 */ -+ } -+ /* normalize to rounding precision -+ */ -+ while ((xm >> (SP_MBITS + 3)) == 0) { -+ xm <<= 1; -+ xe--; -+ } -+ } -+ SPNORMRET2(xs, xe, xm, "sub", x, y); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_tint.c linux-3.4.113/arch/nds32/math-emu/sp_tint.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_tint.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_tint.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,125 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include -+#include "ieee754sp.h" -+ -+int ieee754sp_tint(ieee754sp x) -+{ -+ COMPXSP; -+ -+ CLEARCX; -+ -+ EXPLODEXSP; -+ FLUSHXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); -+ case IEEE754_CLASS_ZERO: -+ return 0; -+ case IEEE754_CLASS_DNORM: -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ if (xe >= 31) { -+ /* look for valid corner case */ -+ if (xe == 31 && xs && xm == SP_HIDDEN_BIT) -+ return -0x80000000; -+ /* Set invalid. We will only use overflow for floating -+ point overflow */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); -+ } -+ /* oh gawd */ -+ if (xe > SP_MBITS) { -+ xm <<= xe - SP_MBITS; -+ } else { -+ u32 residue; -+ int round; -+ int sticky; -+ int odd; -+ -+ if (xe < -1) { -+ residue = xm; -+ round = 0; -+ sticky = residue != 0; -+ xm = 0; -+ } else { -+ /* Shifting a u32 32 times does not work, -+ * so we do it in two steps. Be aware that xe -+ * may be -1 */ -+ residue = xm << (xe + 1); -+ residue <<= 31 - SP_MBITS; -+ round = (residue >> 31) != 0; -+ sticky = (residue << 1) != 0; -+ xm >>= SP_MBITS - xe; -+ } -+ odd = (xm & 0x1) != 0x0; -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ if (round && (sticky || odd)) -+ xm++; -+ break; -+ case IEEE754_RZ: -+ break; -+ case IEEE754_RU: /* toward +Infinity */ -+ if ((round || sticky) && !xs) -+ xm++; -+ break; -+ case IEEE754_RD: /* toward -Infinity */ -+ if ((round || sticky) && xs) -+ xm++; -+ break; -+ } -+ if ((xm >> 31) != 0) { -+ /* This can happen after rounding */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754si_xcpt(ieee754si_indef(), "sp_tint", x); -+ } -+ if (round || sticky) -+ SETCX(IEEE754_INEXACT); -+ } -+ if (xs) -+ return -xm; -+ else -+ return xm; -+} -+ -+unsigned int ieee754sp_tuns(ieee754sp x) -+{ -+ ieee754sp hb = ieee754sp_1e31(); -+ -+ /* what if x < 0 ?? */ -+ if (ieee754sp_lt(x, hb)) -+ return (unsigned)ieee754sp_tint(x); -+ -+ return (unsigned)ieee754sp_tint(ieee754sp_sub(x, hb)) | -+ ((unsigned)1 << 31); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/math-emu/sp_tlong.c linux-3.4.113/arch/nds32/math-emu/sp_tlong.c ---- linux-3.4.113.orig/arch/nds32/math-emu/sp_tlong.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/math-emu/sp_tlong.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,119 @@ -+/* IEEE754 floating point arithmetic -+ * single precision -+ */ -+/* -+ * MIPS floating point support -+ * Copyright (C) 1994-2000 Algorithmics Ltd. -+ * http://www.algor.co.uk -+ * -+ * ######################################################################## -+ * -+ * This program is free software; you can distribute it and/or modify it -+ * under the terms of the GNU General Public License (Version 2) as -+ * published by the Free Software Foundation. -+ * -+ * This program is distributed in the hope it will be useful, but WITHOUT -+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or -+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License -+ * for more details. -+ * -+ * You should have received a copy of the GNU General Public License along -+ * with this program; if not, write to the Free Software Foundation, Inc., -+ * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. -+ * -+ * ######################################################################## -+ */ -+ -+#include "ieee754sp.h" -+ -+s64 ieee754sp_tlong(ieee754sp x) -+{ -+ COMPXDP; /* <-- need 64-bit mantissa tmp */ -+ -+ CLEARCX; -+ -+ EXPLODEXSP; -+ FLUSHXSP; -+ -+ switch (xc) { -+ case IEEE754_CLASS_SNAN: -+ case IEEE754_CLASS_QNAN: -+ case IEEE754_CLASS_INF: -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); -+ case IEEE754_CLASS_ZERO: -+ return 0; -+ case IEEE754_CLASS_DNORM: -+ case IEEE754_CLASS_NORM: -+ break; -+ } -+ if (xe >= 63) { -+ /* look for valid corner case */ -+ if (xe == 63 && xs && xm == SP_HIDDEN_BIT) -+ return -0x8000000000000000LL; -+ /* Set invalid. We will only use overflow for floating -+ point overflow */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); -+ } -+ /* oh gawd */ -+ if (xe > SP_MBITS) { -+ xm <<= xe - SP_MBITS; -+ } else if (xe < SP_MBITS) { -+ u32 residue; -+ int round; -+ int sticky; -+ int odd; -+ -+ if (xe < -1) { -+ residue = xm; -+ round = 0; -+ sticky = residue != 0; -+ xm = 0; -+ } else { -+ residue = xm << (32 - SP_MBITS + xe); -+ round = (residue >> 31) != 0; -+ sticky = (residue << 1) != 0; -+ xm >>= SP_MBITS - xe; -+ } -+ odd = (xm & 0x1) != 0x0; -+ switch (ieee754_csr.rm) { -+ case IEEE754_RN: -+ if (round && (sticky || odd)) -+ xm++; -+ break; -+ case IEEE754_RZ: -+ break; -+ case IEEE754_RU: /* toward +Infinity */ -+ if ((round || sticky) && !xs) -+ xm++; -+ break; -+ case IEEE754_RD: /* toward -Infinity */ -+ if ((round || sticky) && xs) -+ xm++; -+ break; -+ } -+ if ((xm >> 63) != 0) { -+ /* This can happen after rounding */ -+ SETCX(IEEE754_INVALID_OPERATION); -+ return ieee754di_xcpt(ieee754di_indef(), "sp_tlong", x); -+ } -+ if (round || sticky) -+ SETCX(IEEE754_INEXACT); -+ } -+ if (xs) -+ return -xm; -+ else -+ return xm; -+} -+ -+u64 ieee754sp_tulong(ieee754sp x) -+{ -+ ieee754sp hb = ieee754sp_1e63(); -+ -+ /* what if x < 0 ?? */ -+ if (ieee754sp_lt(x, hb)) -+ return (u64) ieee754sp_tlong(x); -+ -+ return (u64) ieee754sp_tlong(ieee754sp_sub(x, hb)) | (1ULL << 63); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/mm/alignment.c linux-3.4.113/arch/nds32/mm/alignment.c ---- linux-3.4.113.orig/arch/nds32/mm/alignment.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/alignment.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,560 @@ -+/* -+ * linux/arch/nds32/mm/alignment.c -+ * -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+ -+#include -+ -+#ifdef CONFIG_PROC_FS -+extern struct proc_dir_entry *proc_dir_cpu; -+#endif -+ -+#define DEBUG(enable, tagged, ...) \ -+ do{ \ -+ if (enable) { \ -+ if (tagged) \ -+ printk(KERN_WARNING "[ %30s() ] ", __func__); \ -+ printk(KERN_WARNING __VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#define RT(inst) (((inst) >> 20) & 0x1FUL) -+#define RA(inst) (((inst) >> 15) & 0x1FUL) -+#define RB(inst) (((inst) >> 10) & 0x1FUL) -+#define SV(inst) (((inst) >> 8) & 0x3UL) -+#define IMM(inst) (((inst) >> 0) & 0x3FFFUL) -+ -+#define RA3(inst) (((inst) >> 3) & 0x7UL) -+#define RT3(inst) (((inst) >> 6) & 0x7UL) -+#define IMM3U(inst) (((inst) >> 0) & 0x7UL) -+ -+#define RA5(inst) (((inst) >> 0) & 0x1FUL) -+#define RT4(inst) (((inst) >> 5) & 0xFUL) -+ -+extern int (*do_unaligned_access) -+ (unsigned long entry, unsigned long addr, -+ unsigned long type, struct pt_regs * regs); -+extern int va_present(struct mm_struct *mm, unsigned long addr); -+extern int va_kernel_present(unsigned long addr); -+extern int va_readable(struct pt_regs *regs, unsigned long addr); -+extern int va_writable(struct pt_regs *regs, unsigned long addr); -+ -+static int mode = 0x3; -+module_param(mode, int, 1); -+ -+static inline unsigned long *idx_to_addr(struct pt_regs *regs, int idx) -+{ -+ /* this should be consistent with ptrace.h */ -+ if (idx >= 0 && idx <= 25) /* R0-R25 */ -+ return ®s->NDS32_r0 + idx; -+ else if (idx >= 28 && idx <= 30) /* FP, GP, LP */ -+ return ®s->NDS32_fp + (idx - 28); -+ else if (idx == 31) /* SP */ -+ return ®s->NDS32_sp; -+ else -+ return NULL; /* cause a segfault */ -+} -+ -+static inline unsigned long get_inst(unsigned long addr) -+{ -+ /* FIXME: consider 16-bit inst. */ -+ return be32_to_cpu(get_unaligned((u32 *) addr)); -+} -+ -+static inline unsigned long get_data(unsigned long addr, int len) -+{ -+ if (len == 4) -+ return get_unaligned((u32 *) addr); -+ else -+ return get_unaligned((u16 *) addr); -+} -+ -+static inline void set_data(unsigned long addr, unsigned long val, int len) -+{ -+ if (len == 4) -+ put_unaligned(val, (u32 *) addr); -+ else -+ put_unaligned(val, (u16 *) addr); -+} -+ -+static inline unsigned long sign_extend(unsigned long val, int len) -+{ -+ unsigned long ret = 0; -+ unsigned char *s, *t; -+ int i = 0; -+ -+ val = cpu_to_le32(val); -+ -+ s = (void *)&val; -+ t = (void *)&ret; -+ -+ while (i++ < len) -+ *t++ = *s++; -+ -+ if (((*(t - 1)) & 0x80) && (i < 4)) { -+ -+ while (i++ <= 4) -+ *t++ = 0xff; -+ } -+ -+ return le32_to_cpu(ret); -+} -+ -+static inline int do_16(unsigned long inst, struct pt_regs *regs) -+{ -+ int imm, regular, load, len, addr_mode, idx_mode; -+ unsigned long unaligned_addr, target_val, source_idx, target_idx, -+ shift = 0; -+ switch ((inst >> 9) & 0x3F) { -+ -+ case 0x12: /* LHI333 */ -+ imm = 1; -+ regular = 1; -+ load = 1; -+ len = 2; -+ addr_mode = 3; -+ idx_mode = 3; -+ break; -+ case 0x10: /* LWI333 */ -+ imm = 1; -+ regular = 1; -+ load = 1; -+ len = 4; -+ addr_mode = 3; -+ idx_mode = 3; -+ break; -+ case 0x11: /* LWI333.bi */ -+ imm = 1; -+ regular = 0; -+ load = 1; -+ len = 4; -+ addr_mode = 3; -+ idx_mode = 3; -+ break; -+ case 0x1A: /* LWI450 */ -+ imm = 0; -+ regular = 1; -+ load = 1; -+ len = 4; -+ addr_mode = 5; -+ idx_mode = 4; -+ break; -+ case 0x16: /* SHI333 */ -+ imm = 1; -+ regular = 1; -+ load = 0; -+ len = 2; -+ addr_mode = 3; -+ idx_mode = 3; -+ break; -+ case 0x14: /* SWI333 */ -+ imm = 1; -+ regular = 1; -+ load = 0; -+ len = 4; -+ addr_mode = 3; -+ idx_mode = 3; -+ break; -+ case 0x15: /* SWI333.bi */ -+ imm = 1; -+ regular = 0; -+ load = 0; -+ len = 4; -+ addr_mode = 3; -+ idx_mode = 3; -+ break; -+ case 0x1B: /* SWI450 */ -+ imm = 0; -+ regular = 1; -+ load = 0; -+ len = 4; -+ addr_mode = 5; -+ idx_mode = 4; -+ break; -+ -+ default: -+ return -EFAULT; -+ } -+ -+ if (addr_mode == 3) { -+ unaligned_addr = *idx_to_addr(regs, RA3(inst)); -+ source_idx = RA3(inst); -+ } else { -+ unaligned_addr = *idx_to_addr(regs, RA5(inst)); -+ source_idx = RA5(inst); -+ } -+ -+ if (idx_mode == 3) -+ target_idx = RT3(inst); -+ else -+ target_idx = RT4(inst); -+ -+ if (imm) -+ shift = IMM3U(inst) * len; -+ -+ if (regular) -+ unaligned_addr += shift; -+ else -+ *idx_to_addr(regs, source_idx) = unaligned_addr + shift; -+ -+ if (load) { -+ -+ if (!va_readable(regs, unaligned_addr)) -+ return -EACCES; -+ -+ if (!access_ok(VERIFY_READ, (void *)unaligned_addr, len)) -+ return -EACCES; -+ -+ *idx_to_addr(regs, target_idx) = get_data(unaligned_addr, len); -+ } else { -+ -+ if (!va_writable(regs, unaligned_addr)) -+ return -EACCES; -+ -+ if (!access_ok(VERIFY_WRITE, (void *)unaligned_addr, len)) -+ return -EACCES; -+ -+ target_val = *idx_to_addr(regs, target_idx); -+ set_data(unaligned_addr, target_val, len); -+ } -+ -+ regs->NDS32_ipc += 2; -+ -+ return 0; -+} -+ -+static inline int do_32(unsigned long inst, struct pt_regs *regs) -+{ -+ int imm, regular, load, len, sign_ext; -+ unsigned long unsligned_addr, target_val, shift; -+ -+ unsligned_addr = *idx_to_addr(regs, RA(inst)); -+ -+ switch ((inst >> 25) << 1) { -+ -+ case 0x02: /* LHI */ -+ imm = 1; -+ regular = 1; -+ load = 1; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x0A: /* LHI.bi */ -+ imm = 1; -+ regular = 0; -+ load = 1; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x22: /* LHSI */ -+ imm = 1; -+ regular = 1; -+ load = 1; -+ len = 2; -+ sign_ext = 1; -+ break; -+ case 0x2A: /* LHSI.bi */ -+ imm = 1; -+ regular = 0; -+ load = 1; -+ len = 2; -+ sign_ext = 1; -+ break; -+ case 0x04: /* LWI */ -+ imm = 1; -+ regular = 1; -+ load = 1; -+ len = 4; -+ sign_ext = 0; -+ break; -+ case 0x0C: /* LWI.bi */ -+ imm = 1; -+ regular = 0; -+ load = 1; -+ len = 4; -+ sign_ext = 0; -+ break; -+ case 0x12: /* SHI */ -+ imm = 1; -+ regular = 1; -+ load = 0; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x1A: /* SHI.bi */ -+ imm = 1; -+ regular = 0; -+ load = 0; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x14: /* SWI */ -+ imm = 1; -+ regular = 1; -+ load = 0; -+ len = 4; -+ sign_ext = 0; -+ break; -+ case 0x1C: /* SWI.bi */ -+ imm = 1; -+ regular = 0; -+ load = 0; -+ len = 4; -+ sign_ext = 0; -+ break; -+ -+ default: -+ switch (inst & 0xff) { -+ -+ case 0x01: /* LH */ -+ imm = 0; -+ regular = 1; -+ load = 1; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x05: /* LH.bi */ -+ imm = 0; -+ regular = 0; -+ load = 1; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x11: /* LHS */ -+ imm = 0; -+ regular = 1; -+ load = 1; -+ len = 2; -+ sign_ext = 1; -+ break; -+ case 0x15: /* LHS.bi */ -+ imm = 0; -+ regular = 0; -+ load = 1; -+ len = 2; -+ sign_ext = 1; -+ break; -+ case 0x02: /* LW */ -+ imm = 0; -+ regular = 1; -+ load = 1; -+ len = 4; -+ sign_ext = 0; -+ break; -+ case 0x06: /* LW.bi */ -+ imm = 0; -+ regular = 0; -+ load = 1; -+ len = 4; -+ sign_ext = 0; -+ break; -+ case 0x09: /* SH */ -+ imm = 0; -+ regular = 1; -+ load = 0; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x0D: /* SH.bi */ -+ imm = 0; -+ regular = 0; -+ load = 0; -+ len = 2; -+ sign_ext = 0; -+ break; -+ case 0x0A: /* SW */ -+ imm = 0; -+ regular = 1; -+ load = 0; -+ len = 4; -+ sign_ext = 0; -+ break; -+ case 0x0E: /* SW.bi */ -+ imm = 0; -+ regular = 0; -+ load = 0; -+ len = 4; -+ sign_ext = 0; -+ break; -+ -+ default: -+ return -EFAULT; -+ } -+ } -+ -+ if (imm) -+ shift = IMM(inst) * len; -+ else -+ shift = *idx_to_addr(regs, RB(inst)) << SV(inst); -+ -+ if (regular) -+ unsligned_addr += shift; -+ else -+ *idx_to_addr(regs, RA(inst)) = unsligned_addr + shift; -+ -+ if (load) { -+ -+ if (!va_readable(regs, unsligned_addr)) -+ return -EACCES; -+ -+ if (!access_ok(VERIFY_READ, (void *)unsligned_addr, len)) -+ return -EACCES; -+ -+ if (sign_ext) -+ *idx_to_addr(regs, RT(inst)) = -+ sign_extend(get_data(unsligned_addr, len), len); -+ else -+ *idx_to_addr(regs, RT(inst)) = -+ get_data(unsligned_addr, len); -+ } else { -+ -+ if (!va_writable(regs, unsligned_addr)) -+ return -EACCES; -+ -+ if (!access_ok(VERIFY_WRITE, (void *)unsligned_addr, len)) -+ return -EACCES; -+ -+ target_val = *idx_to_addr(regs, RT(inst)); -+ set_data(unsligned_addr, target_val, len); -+ } -+ -+ regs->NDS32_ipc += 4; -+ -+ return 0; -+} -+ -+static int _do_unaligned_access(unsigned long entry, unsigned long addr, -+ unsigned long type, struct pt_regs *regs) -+{ -+ unsigned long inst; -+ int ret = -EFAULT; -+ -+ if (user_mode(regs)) { -+ /* user mode */ -+ if (!va_present(current->mm, addr)) -+ return ret; -+ } else { -+ /* kernel mode */ -+ if (!va_kernel_present(addr)) -+ return ret; -+ } -+ -+ inst = get_inst(regs->NDS32_ipc); -+ -+ DEBUG(mode & 0x04, 1, -+ "Faulting Addr: 0x%08lx, PC: 0x%08lx [ 0x%08lx ]\n", addr, -+ regs->NDS32_ipc, inst); -+ -+ if ((user_mode(regs) && (mode & 0x01)) -+ || (!user_mode(regs) && (mode & 0x02))) { -+ -+ mm_segment_t seg = get_fs(); -+ -+ set_fs(KERNEL_DS); -+ -+ if (inst & 0x80000000) -+ ret = do_16((inst >> 16) & 0xffff, regs); -+ else -+ ret = do_32(inst, regs); -+ -+ set_fs(seg); -+ } -+ -+ return ret; -+} -+ -+#ifdef CONFIG_PROC_FS -+ -+static int proc_alignment_read(char *page, char **start, off_t off, int count, -+ int *eof, void *data) -+{ -+ char *p = page; -+ int len; -+ -+ p += sprintf(p, "(0x01) User Mode: %s\n", mode & 0x01 ? "on" : "off"); -+ p += sprintf(p, "(0x02) Kernel Mode: %s\n", mode & 0x02 ? "on" : "off"); -+ p += sprintf(p, "(0x04) Warning: %s\n", mode & 0x04 ? "on" : "off"); -+ -+ len = (p - page) - off; -+ if (len < 0) -+ len = 0; -+ -+ *eof = (len <= count) ? 1 : 0; -+ *start = page + off; -+ -+ return len; -+} -+ -+#define INPUTLEN 12 /* '0' + 'x' + 8digit + '\n' + '\0' */ -+ -+static int proc_alignment_write(struct file *file, const char __user * buffer, -+ unsigned long count, void *data) -+{ -+ unsigned long en; -+ char *endp; -+ char inbuf[INPUTLEN]; -+ -+ if (count > INPUTLEN - 1) -+ return -EFAULT; -+ -+ if (copy_from_user(inbuf, buffer, count)) -+ return -EFAULT; -+ -+ inbuf[count - 1] = '\0'; -+ -+ en = simple_strtoul(inbuf, &endp, 0); -+ if (en > 0x07) -+ return -EFAULT; -+ -+ mode = en & 0x7; -+ -+ return count; -+} -+ -+#endif /* CONFIG_PROC_FS */ -+ -+static int __init unaligned_access_init(void) -+{ -+#ifdef CONFIG_PROC_FS -+ static struct proc_dir_entry *res_alignment; -+ -+ if (!proc_dir_cpu) -+ if (!(proc_dir_cpu = proc_mkdir("cpu", NULL))) -+ return -ENOMEM; -+ -+ if (! -+ (res_alignment = -+ create_proc_entry("alignment", S_IWUSR | S_IRUGO, proc_dir_cpu))) -+ return -ENOMEM; -+ -+ res_alignment->read_proc = proc_alignment_read; -+ res_alignment->write_proc = proc_alignment_write; -+#endif -+ do_unaligned_access = _do_unaligned_access; -+ -+ return 0; -+} -+ -+static void __exit unaligned_access_exit(void) -+{ -+#ifdef CONFIG_PROC_FS -+ remove_proc_entry("alignment", proc_dir_cpu); -+#endif -+ do_unaligned_access = NULL; -+} -+ -+MODULE_AUTHOR("Roy Lee"); -+MODULE_DESCRIPTION("Unaligned Access Handler"); -+MODULE_LICENSE("GPL"); -+ -+module_init(unaligned_access_init); -+module_exit(unaligned_access_exit); -diff -Nur linux-3.4.113.orig/arch/nds32/mm/cacheflush.c linux-3.4.113/arch/nds32/mm/cacheflush.c ---- linux-3.4.113.orig/arch/nds32/mm/cacheflush.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/cacheflush.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,355 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern struct cache_info L1_cache_info[2]; -+ -+#ifdef CONFIG_CPU_CACHE_NONALIASING -+void flush_cache_mm(struct mm_struct *mm) -+{ -+} -+ -+void flush_cache_dup_mm(struct mm_struct *mm) -+{ -+} -+ -+void flush_cache_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+} -+ -+void flush_cache_page(struct vm_area_struct *vma, -+ unsigned long addr, unsigned long pfn) -+{ -+} -+ -+void flush_cache_vmap(unsigned long start, unsigned long end) -+{ -+} -+ -+void flush_cache_vunmap(unsigned long start, unsigned long end) -+{ -+} -+ -+void flush_dcache_page(struct page *page) -+{ -+ struct address_space *mapping; -+ -+ if (!PageHighMem(page)) { -+ mapping = page_mapping(page); -+ if (mapping && !mapping_mapped(mapping)) -+ set_bit(PG_dcache_dirty, &page->flags); -+ else -+ cpu_dcache_wbinval_page((unsigned long) -+ page_address(page)); -+ } else { -+ unsigned long kaddr = (unsigned long)kmap_atomic(page); -+ cpu_dcache_wbinval_page(kaddr); -+ kunmap_atomic((void *)kaddr); -+ } -+} -+ -+void copy_to_user_page(struct vm_area_struct *vma, struct page *page, -+ unsigned long vaddr, void *dst, void *src, int len) -+{ -+ unsigned long line_size, start, end; -+ -+ memcpy(dst, src, len); -+ if (vma->vm_flags & VM_EXEC) { -+ line_size = L1_cache_info[DCACHE].line_size; -+ start = (unsigned long)dst & ~(line_size - 1); -+ end = -+ ((unsigned long)dst + len + line_size - 1) & ~(line_size - -+ 1); -+ cpu_cache_wbinval_range(start, end, 1); -+ } -+} -+ -+void copy_from_user_page(struct vm_area_struct *vma, struct page *page, -+ unsigned long vaddr, void *dst, void *src, int len) -+{ -+ memcpy(dst, src, len); -+} -+ -+void flush_icache_range(unsigned long start, unsigned long end) -+{ -+ cpu_cache_wbinval_range(start, end, 1); -+} -+ -+void flush_icache_page(struct vm_area_struct *vma, struct page *page) -+{ -+} -+ -+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, -+ pte_t * pte) -+{ -+ struct page *page; -+ unsigned long pfn = pte_pfn(*pte); -+ -+ if (!pfn_valid(pfn)) -+ return; -+ -+ if (vma->vm_mm == current->active_mm) -+ asm("mtsr %1, $mr2\ndsb\n" -+ "tlbop %0, RWR\nisb\n" -+ ::"r"(*pte), "r"(addr)); -+ -+ page = pfn_to_page(pfn); -+ -+ if ((test_and_clear_bit(PG_dcache_dirty, &page->flags)) || -+ (vma->vm_flags & VM_EXEC)) { -+ -+ if (!PageHighMem(page)) { -+ cpu_cache_wbinval_page((unsigned long) -+ page_address(page), -+ vma->vm_flags & VM_EXEC); -+ } else { -+ unsigned long kaddr = (unsigned long)kmap_atomic(page); -+ cpu_cache_wbinval_page(kaddr, vma->vm_flags & VM_EXEC); -+ kunmap_atomic((void *)kaddr); -+ } -+ } -+} -+#else -+int va_present(struct mm_struct *mm, unsigned long addr); -+ -+static inline unsigned long aliasing(unsigned long addr, unsigned long page) -+{ -+ return ((addr & PAGE_MASK) ^ page) & (REALSHMLBA - 1); -+} -+ -+static inline unsigned long kremap0(unsigned long uaddr, unsigned long pa) -+{ -+ unsigned long kaddr, pte; -+ -+#define BASE_ADDR0 0xffffc000 -+ kaddr = BASE_ADDR0 | (uaddr & L1_cache_info[DCACHE].aliasing_mask); -+ pte = (pa | PAGE_KERNEL); -+ asm("mtsr %1, $mr2\ndsb\n" -+ "tlbop %0, RWLK\nisb\n" -+ ::"r"(pte), "r"(kaddr)); -+ return kaddr; -+} -+ -+static inline void kunmap01(unsigned long kaddr) -+{ -+ asm volatile ("tlbop %0, UNLK\n\t" -+ "tlbop %0, INV\n\t" -+ ::"r" (kaddr)); -+} -+ -+static inline unsigned long kremap1(unsigned long uaddr, unsigned long pa) -+{ -+ unsigned long kaddr, pte; -+ -+#define BASE_ADDR1 0xffff8000 -+ kaddr = BASE_ADDR1 | (uaddr & L1_cache_info[DCACHE].aliasing_mask); -+ pte = (pa | PAGE_KERNEL); -+ asm("mtsr %1, $mr2\ndsb\n" -+ "tlbop %0, RWLK\nisb\n" -+ ::"r"(pte), "r"(kaddr)); -+ return kaddr; -+} -+ -+void flush_cache_mm(struct mm_struct *mm) -+{ -+ cpu_dcache_wbinval_all(); -+ cpu_icache_inval_all(); -+} -+ -+void flush_cache_dup_mm(struct mm_struct *mm) -+{ -+} -+ -+void flush_cache_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+ if ((end - start) > 8 * PAGE_SIZE) { -+ cpu_dcache_wbinval_all(); -+ if (vma->vm_flags & VM_EXEC) -+ cpu_icache_inval_all(); -+ return; -+ } -+ -+ while (start < end) { -+ if (va_present(vma->vm_mm, start)) -+ cpu_cache_wbinval_page(start, vma->vm_flags & VM_EXEC); -+ start += PAGE_SIZE; -+ } -+} -+ -+void flush_cache_page(struct vm_area_struct *vma, -+ unsigned long addr, unsigned long pfn) -+{ -+ unsigned long vto, flags; -+ -+ local_irq_save(flags); -+ vto = kremap0(addr, pfn << PAGE_SHIFT); -+ cpu_cache_wbinval_page(vto, vma->vm_flags & VM_EXEC); -+ kunmap01(vto); -+ local_irq_restore(flags); -+} -+ -+void flush_cache_vmap(unsigned long start, unsigned long end) -+{ -+ cpu_dcache_wbinval_all(); -+} -+ -+void flush_cache_vunmap(unsigned long start, unsigned long end) -+{ -+ cpu_dcache_wbinval_all(); -+} -+ -+void copy_user_highpage(struct page *to, struct page *from, -+ unsigned long vaddr, struct vm_area_struct *vma) -+{ -+ unsigned long vto, vfrom, flags, kto, kfrom, pfrom, pto; -+ kto = ((unsigned long)page_address(to) & PAGE_MASK); -+ kfrom = ((unsigned long)page_address(from) & PAGE_MASK); -+ pto = page_to_phys(to); -+ pfrom = page_to_phys(from); -+ -+ if (aliasing(vaddr, (unsigned long)kfrom)) -+ cpu_dcache_wb_page((unsigned long)kfrom); -+ if (aliasing(vaddr, (unsigned long)kto)) -+ cpu_dcache_inval_page((unsigned long)kto); -+ local_irq_save(flags); -+ vto = kremap0(vaddr, pto); -+ vfrom = kremap1(vaddr, pfrom); -+ copy_page((void *)vto, (void *)vfrom); -+ kunmap01(vfrom); -+ kunmap01(vto); -+ local_irq_restore(flags); -+} -+ -+EXPORT_SYMBOL(copy_user_highpage); -+ -+void clear_user_highpage(struct page *page, unsigned long vaddr) -+{ -+ unsigned long vto, flags, kto; -+ -+ kto = ((unsigned long)page_address(page) & PAGE_MASK); -+ -+ local_irq_save(flags); -+ if (aliasing(kto, vaddr) && kto != 0) { -+ cpu_dcache_inval_page(kto); -+ cpu_icache_inval_page(kto); -+ } -+ vto = kremap0(vaddr, page_to_phys(page)); -+ clear_page((void *)vto); -+ kunmap01(vto); -+ local_irq_restore(flags); -+} -+ -+EXPORT_SYMBOL(clear_user_highpage); -+ -+void flush_dcache_page(struct page *page) -+{ -+ struct address_space *mapping; -+ -+ mapping = page_mapping(page); -+ if (mapping && !mapping_mapped(mapping)) -+ set_bit(PG_dcache_dirty, &page->flags); -+ else { -+ int i, pc; -+ unsigned long vto, kaddr, flags; -+ cpu_dcache_wbinval_page((unsigned long)page_address(page)); -+ kaddr = (unsigned long)page_address(page); -+ pc = CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE) / PAGE_SIZE; -+ for (i = 0; i < pc; i++) { -+ local_irq_save(flags); -+ vto = kremap0(kaddr + i * PAGE_SIZE, __pa(kaddr)); -+ cpu_dcache_wbinval_page(vto); -+ kunmap01(vto); -+ local_irq_restore(flags); -+ } -+ } -+} -+ -+void copy_to_user_page(struct vm_area_struct *vma, struct page *page, -+ unsigned long vaddr, void *dst, void *src, int len) -+{ -+ unsigned long line_size, start, end, vto, flags; -+ -+ local_irq_save(flags); -+ vto = kremap0(vaddr, page_to_phys(page)); -+ dst = (void *)(vto | (vaddr & (PAGE_SIZE - 1))); -+ memcpy(dst, src, len); -+ if (vma->vm_flags & VM_EXEC) { -+ line_size = L1_cache_info[DCACHE].line_size; -+ start = (unsigned long)dst & ~(line_size - 1); -+ end = -+ ((unsigned long)dst + len + line_size - 1) & ~(line_size - -+ 1); -+ cpu_cache_wbinval_range(start, end, 1); -+ } -+ kunmap01(vto); -+ local_irq_restore(flags); -+} -+ -+void copy_from_user_page(struct vm_area_struct *vma, struct page *page, -+ unsigned long vaddr, void *dst, void *src, int len) -+{ -+ unsigned long vto, flags; -+ -+ local_irq_save(flags); -+ vto = kremap0(vaddr, page_to_phys(page)); -+ src = (void *)(vto | (vaddr & (PAGE_SIZE - 1))); -+ memcpy(dst, src, len); -+ kunmap01(vto); -+ local_irq_restore(flags); -+} -+ -+void flush_anon_page(struct vm_area_struct *vma, -+ struct page *page, unsigned long vaddr) -+{ -+ if (!PageAnon(page)) -+ return; -+ -+ if (vma->vm_mm != current->active_mm) -+ return; -+ -+ cpu_cache_wbinval_page(vaddr & PAGE_MASK, vma->vm_flags & VM_EXEC); -+} -+ -+void flush_kernel_dcache_page(struct page *page) -+{ -+ cpu_dcache_wbinval_page((unsigned long)page_address(page)); -+} -+ -+void flush_icache_range(unsigned long start, unsigned long end) -+{ -+ cpu_cache_wbinval_range(start, end, 1); -+} -+ -+void flush_icache_page(struct vm_area_struct *vma, struct page *page) -+{ -+} -+ -+void update_mmu_cache(struct vm_area_struct *vma, unsigned long addr, -+ pte_t * pte) -+{ -+ struct page *page; -+ unsigned long pfn = pte_pfn(*pte); -+ -+ if (!pfn_valid(pfn)) -+ return; -+ -+ if (vma->vm_mm == current->active_mm) { -+ asm("mtsr %1, $mr2\ndsb\n" -+ "tlbop %0, RWR\nisb\n" -+ ::"r"(*pte), "r"(addr)); -+ } -+ -+ page = pfn_to_page(pfn); -+ if (test_and_clear_bit(PG_dcache_dirty, &page->flags) || -+ (vma->vm_flags & VM_EXEC)) -+ cpu_dcache_wbinval_page((unsigned long)page_address(page)); -+} -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/mm/cctl.c linux-3.4.113/arch/nds32/mm/cctl.c ---- linux-3.4.113.orig/arch/nds32/mm/cctl.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/cctl.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,284 @@ -+/* -+ * linux/arch/nds32/mm/cctl.c -+ * -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 "cctl.h" -+ -+#define DEBUG( enable, tagged, ...) \ -+ do{ \ -+ if( enable){ \ -+ if( tagged) \ -+ printk( "[ %30s() ] ", __func__); \ -+ printk( __VA_ARGS__); \ -+ } \ -+ } while( 0) -+ -+static int debug = 1; -+module_param(debug, int, 0); -+ -+static int proc_read_cache_en(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ -+ if (!strncmp(data, "ic_en", 7)) -+ return sprintf(page, "I-cache: %s\n", -+ (GET_CACHE_CTL() & CACHE_CTL_mskIC_EN) ? -+ "Enabled" : "Disabled"); -+ else -+ return sprintf(page, "D-cache: %s\n", -+ (GET_CACHE_CTL() & CACHE_CTL_mskDC_EN) ? -+ "Enabled" : "Disabled"); -+} -+ -+static int proc_write_cache_en(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ -+ unsigned long en, saved_gie; -+ char inbuf[INPUTLEN]; -+ -+ if (count > INPUTLEN - 1) -+ count = INPUTLEN - 1; -+ -+ if (copy_from_user(inbuf, buffer, count)) -+ return -EFAULT; -+ -+ inbuf[count] = '\0'; -+ -+ if (!sscanf(inbuf, "%lu", &en) || en > 1) -+ return -EFAULT; -+ -+ GIE_SAVE(&saved_gie); -+ -+ if (!strncmp(data, "ic_en", 7)) { -+ -+ if (en && !(GET_CACHE_CTL() & CACHE_CTL_mskIC_EN)) { -+ -+ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskIC_EN); -+ DEBUG(debug, 1, "I-cache: Enabled\n"); -+ } else if (!en && (GET_CACHE_CTL() & CACHE_CTL_mskIC_EN)) { -+ -+ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskIC_EN); -+ cpu_icache_inval_all(); -+ DEBUG(debug, 1, "I-cache: Disabled\n"); -+ } -+ } else { -+ if (en && !(GET_CACHE_CTL() & CACHE_CTL_mskDC_EN)) { -+ -+ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN); -+ DEBUG(debug, 1, "D-cache: Enabled\n"); -+ } else if (!en && (GET_CACHE_CTL() & CACHE_CTL_mskDC_EN)) { -+ -+ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN); -+ cpu_dcache_wbinval_all(); -+ DEBUG(debug, 1, "D-cache: Disabled\n"); -+ } -+ } -+ -+ GIE_RESTORE(saved_gie); -+ -+ return count; -+} -+ -+struct entry_struct proc_table_cache_en[] = { -+ -+ {"ic_en", 0644, proc_read_cache_en, proc_write_cache_en}, -+ {"dc_en", 0644, proc_read_cache_en, proc_write_cache_en}, -+ {NULL, 0, NULL, NULL} -+}; -+ -+static int sprint_cache_sdz(char *buf, unsigned long size, unsigned long way, -+ unsigned sdz) -+{ -+ -+ return sprintf(buf, "[%c] %luK x %lu\n[%c] %luK x %lu\n" -+ "[%c] %luK x %lu\n[%c] %luK x %lu\n", -+ (sdz == 0) ? '*' : ' ', (size / 1024), way, -+ (sdz == 1) ? '*' : ' ', (size / 1024), way / 2, -+ (sdz == 2) ? '*' : ' ', (size / 1024) / 2, way, -+ (sdz == 3) ? '*' : ' ', (size / 1024) / 2, way / 2); -+} -+ -+static int proc_read_cache_sdz(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ -+ if (!strncmp(data, "ic_sdz", 7)) { -+ -+ return sprint_cache_sdz(page, -+ CACHE_LINE_SIZE(ICACHE) * -+ CACHE_SET(ICACHE), CACHE_WAY(ICACHE), -+ (GET_SDZ_CTL() & SDZ_CTL_mskICDZ) >> -+ SDZ_CTL_offICDZ); -+ } else { -+ return sprint_cache_sdz(page, -+ CACHE_LINE_SIZE(DCACHE) * -+ CACHE_SET(DCACHE), CACHE_WAY(DCACHE), -+ (GET_SDZ_CTL() & SDZ_CTL_mskDCDZ) >> -+ SDZ_CTL_offDCDZ); -+ } -+} -+ -+static int proc_write_cache_sdz(struct file *file, const char *buffer, -+ unsigned long count, void *data) -+{ -+ -+ unsigned long mode, saved_gie, saved_cctl; -+ char inbuf[INPUTLEN]; -+ -+ if (count > INPUTLEN - 1) -+ count = INPUTLEN - 1; -+ -+ if (copy_from_user(inbuf, buffer, count)) -+ return -EFAULT; -+ -+ inbuf[count] = '\0'; -+ -+ if (!sscanf(inbuf, "%lu", &mode) || mode > 3) -+ return -EFAULT; -+ -+ GIE_SAVE(&saved_gie); -+ -+ saved_cctl = GET_CACHE_CTL(); -+ DEBUG(debug, 1, "saved_gie: %ld, saved_cctl: 0x%08lx\n", saved_gie, -+ saved_cctl); -+ -+ if (!strncmp(data, "ic_sdz", 7)) { -+ -+ DEBUG(debug, 1, "IC_SDZ: mode %ld\n", mode); -+ -+ if (mode == 2 || mode == 3) { -+ -+ if (CACHE_LINE_SIZE(ICACHE) * CACHE_SET(ICACHE) / 2 < -+ 4096) { -+ -+ GIE_RESTORE(saved_gie); -+ DEBUG(debug, 1, "Error: way size < 4096\n"); -+ return -1; -+ } -+ } -+ -+ /* turn off and flush cache */ -+ DEBUG(debug, 1, "turning off cache\n"); -+ SET_CACHE_CTL(saved_cctl & ~CACHE_CTL_mskIC_EN); -+ DEBUG(debug, 1, "flushing cache\n"); -+ cpu_icache_inval_all(); -+ -+ /* perform down size operation */ -+ DEBUG(debug, 1, "downsizing cache\n"); -+ SET_SDZ_CTL((GET_SDZ_CTL() & ~SDZ_CTL_mskICDZ) | -+ (mode << SDZ_CTL_offICDZ)); -+ } else { -+ -+ DEBUG(debug, 1, "DC_SDZ: mode %ld\n", mode); -+ -+ if (mode == 2 || mode == 3) { -+ -+ if (CACHE_LINE_SIZE(DCACHE) * CACHE_SET(DCACHE) / 2 < -+ 4096) { -+ -+ GIE_RESTORE(saved_gie); -+ DEBUG(debug, 1, "Error: way size < 4096\n"); -+ return -1; -+ } -+ } -+ -+ /* turn off and flush cache */ -+ DEBUG(debug, 1, "turning off cache\n"); -+ SET_CACHE_CTL(saved_cctl & ~CACHE_CTL_mskDC_EN); -+ DEBUG(debug, 1, "flushing cache\n"); -+ cpu_dcache_wbinval_all(); -+ -+ /* perform down size operation */ -+ DEBUG(debug, 1, "downsizing cache\n"); -+ SET_SDZ_CTL((GET_SDZ_CTL() & ~SDZ_CTL_mskDCDZ) | -+ (mode << SDZ_CTL_offDCDZ)); -+ } -+ -+ /* turn on cache ( if it was enabled) */ -+ DEBUG(debug, 1, "restoring saved_cctl : 0x%08lx\n", saved_cctl); -+ SET_CACHE_CTL(saved_cctl); -+ -+ DEBUG(debug, 1, "restoring saved_git: %ld\n", saved_gie); -+ GIE_RESTORE(saved_gie); -+ -+ return count; -+} -+ -+struct entry_struct proc_table_cache_sdz[] = { -+ -+ {"ic_sdz", 0644, proc_read_cache_sdz, proc_write_cache_sdz}, -+ {"dc_sdz", 0644, proc_read_cache_sdz, proc_write_cache_sdz}, -+ {NULL, 0, NULL, NULL} -+}; -+ -+static struct proc_dir_entry *proc_cctl; -+ -+static void create_seq_entry(struct entry_struct *e, mode_t mode, -+ struct proc_dir_entry *parent) -+{ -+ -+ struct proc_dir_entry *entry = create_proc_entry(e->name, mode, parent); -+ -+ if (entry) { -+ -+ entry->read_proc = e->readop; -+ entry->write_proc = e->writeop; -+ entry->data = e->name; -+ } -+} -+ -+static void install_proc_table(struct entry_struct *table) -+{ -+ -+ while (table->name) { -+ -+ create_seq_entry(table, table->perm, proc_cctl); -+ table++; -+ } -+} -+ -+static void remove_proc_table(struct entry_struct *table) -+{ -+ -+ while (table->name) { -+ -+ remove_proc_entry(table->name, proc_cctl); -+ table++; -+ } -+} -+ -+static int __init init_cctl(void) -+{ -+ -+ DEBUG(debug, 1, "CCTL module registered\n"); -+ -+ proc_cctl = proc_mkdir("cctl", NULL); -+ -+ install_proc_table(proc_table_cache_en); -+ install_proc_table(proc_table_cache_sdz); -+ -+ return 0; -+} -+ -+static void __exit cleanup_cctl(void) -+{ -+ -+ remove_proc_table(proc_table_cache_sdz); -+ remove_proc_table(proc_table_cache_en); -+ remove_proc_entry("cctl", NULL); -+ -+ DEBUG(debug, 1, "CCTL module unregistered\n"); -+} -+ -+module_init(init_cctl); -+module_exit(cleanup_cctl); -+ -+MODULE_LICENSE("GPL"); -+MODULE_DESCRIPTION("Userspace Cache Control Module"); -diff -Nur linux-3.4.113.orig/arch/nds32/mm/cctl.h linux-3.4.113/arch/nds32/mm/cctl.h ---- linux-3.4.113.orig/arch/nds32/mm/cctl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/cctl.h 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,22 @@ -+#ifndef CCTL_H -+#define CCTL_H -+ -+#include -+#include -+#include -+#include -+ -+#define INPUTLEN 32 -+ -+extern void cpu_icache_flush(void); -+extern void cpu_dcache_flush(void); -+ -+struct entry_struct{ -+ -+ char *name; -+ int perm; -+ read_proc_t *readop; -+ write_proc_t *writeop; -+}; -+ -+#endif /* CCTL_H */ -diff -Nur linux-3.4.113.orig/arch/nds32/mm/consistent.c linux-3.4.113/arch/nds32/mm/consistent.c ---- linux-3.4.113.orig/arch/nds32/mm/consistent.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/consistent.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,448 @@ -+/* -+ * linux/arch/nds32/mm/consistent.c -+ * -+ * Copyright (C) 2000-2004 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * DMA uncached mapping support. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* -+ * This is the page table (2MB) covering uncached, DMA consistent allocations -+ */ -+static pte_t *consistent_pte; -+static DEFINE_RAW_SPINLOCK(consistent_lock); -+ -+/* -+ * VM region handling support. -+ * -+ * This should become something generic, handling VM region allocations for -+ * vmalloc and similar (ioremap, module space, etc). -+ * -+ * I envisage vmalloc()'s supporting vm_struct becoming: -+ * -+ * struct vm_struct { -+ * struct vm_region region; -+ * unsigned long flags; -+ * struct page **pages; -+ * unsigned int nr_pages; -+ * unsigned long phys_addr; -+ * }; -+ * -+ * get_vm_area() would then call vm_region_alloc with an appropriate -+ * struct vm_region head (eg): -+ * -+ * struct vm_region vmalloc_head = { -+ * .vm_list = LIST_HEAD_INIT(vmalloc_head.vm_list), -+ * .vm_start = VMALLOC_START, -+ * .vm_end = VMALLOC_END, -+ * }; -+ * -+ * However, vmalloc_head.vm_start is variable (typically, it is dependent on -+ * the amount of RAM found at boot time.) I would imagine that get_vm_area() -+ * would have to initialise this each time prior to calling vm_region_alloc(). -+ */ -+struct arch_vm_region { -+ struct list_head vm_list; -+ unsigned long vm_start; -+ unsigned long vm_end; -+ struct page *vm_pages; -+}; -+ -+static struct arch_vm_region consistent_head = { -+ .vm_list = LIST_HEAD_INIT(consistent_head.vm_list), -+ .vm_start = CONSISTENT_BASE, -+ .vm_end = CONSISTENT_END, -+}; -+ -+static struct arch_vm_region *vm_region_alloc(struct arch_vm_region *head, -+ size_t size, int gfp) -+{ -+ unsigned long addr = head->vm_start, end = head->vm_end - size; -+ unsigned long flags; -+ struct arch_vm_region *c, *new; -+ -+ new = kmalloc(sizeof(struct arch_vm_region), gfp); -+ if (!new) -+ goto out; -+ -+ raw_spin_lock_irqsave(&consistent_lock, flags); -+ -+ list_for_each_entry(c, &head->vm_list, vm_list) { -+ if ((addr + size) < addr) -+ goto nospc; -+ if ((addr + size) <= c->vm_start) -+ goto found; -+ addr = c->vm_end; -+ if (addr > end) -+ goto nospc; -+ } -+ -+found: -+ /* -+ * Insert this entry _before_ the one we found. -+ */ -+ list_add_tail(&new->vm_list, &c->vm_list); -+ new->vm_start = addr; -+ new->vm_end = addr + size; -+ -+ raw_spin_unlock_irqrestore(&consistent_lock, flags); -+ return new; -+ -+nospc: -+ raw_spin_unlock_irqrestore(&consistent_lock, flags); -+ kfree(new); -+out: -+ return NULL; -+} -+ -+static struct arch_vm_region *vm_region_find(struct arch_vm_region *head, -+ unsigned long addr) -+{ -+ struct arch_vm_region *c; -+ -+ list_for_each_entry(c, &head->vm_list, vm_list) { -+ if (c->vm_start == addr) -+ goto out; -+ } -+ c = NULL; -+out: -+ return c; -+} -+ -+#ifdef CONFIG_HUGETLB_PAGE -+#error ARM Coherent DMA allocator does not (yet) support huge TLB -+#endif -+ -+static void *__dma_alloc(struct device *dev, size_t size, dma_addr_t * handle, -+ int gfp, pgprot_t prot) -+{ -+ struct page *page; -+ struct arch_vm_region *c; -+ unsigned long order; -+ unsigned int i; -+ u64 mask = ISA_DMA_THRESHOLD, limit; -+ -+ if (!consistent_pte) { -+ printk(KERN_ERR "%s: not initialised\n", __func__); -+ dump_stack(); -+ return NULL; -+ } -+ -+ if (dev) { -+ mask = dev->coherent_dma_mask; -+ -+ /* -+ * Sanity check the DMA mask - it must be non-zero, and -+ * must be able to be satisfied by a DMA allocation. -+ */ -+ if (mask == 0) { -+ dev_warn(dev, "coherent DMA mask is unset\n"); -+ goto no_page; -+ } -+ -+ if ((~mask) & ISA_DMA_THRESHOLD) { -+ dev_warn(dev, "coherent DMA mask %#llx is smaller " -+ "than system GFP_DMA mask %#llx\n", -+ mask, (unsigned long long)ISA_DMA_THRESHOLD); -+ goto no_page; -+ } -+ } -+ -+ /* -+ * Sanity check the allocation size. -+ */ -+ size = PAGE_ALIGN(size); -+ limit = (mask + 1) & ~mask; -+ if ((limit && size >= limit) || -+ size >= (CONSISTENT_END - CONSISTENT_BASE)) { -+ printk(KERN_WARNING "coherent allocation too big " -+ "(requested %#x mask %#llx)\n", size, mask); -+ goto no_page; -+ } -+ -+ order = get_order(size); -+ -+ if (mask != 0xffffffff) -+ gfp |= GFP_DMA; -+ -+ page = alloc_pages(gfp, order); -+ if (!page) -+ goto no_page; -+ -+ for (i = 1; i < (1 << order); i++) -+ atomic_set(&(page + i)->_count, 1); -+ -+ /* -+ * Invalidate any data that might be lurking in the -+ * kernel direct-mapped region for device DMA. -+ */ -+ { -+ unsigned long kaddr = (unsigned long)page_address(page); -+ memset(page_address(page), 0, size); -+ cpu_dma_wbinval_range(kaddr, kaddr + size); -+ } -+ -+ /* -+ * Allocate a virtual address in the consistent mapping region. -+ */ -+ c = vm_region_alloc(&consistent_head, size, -+ gfp & ~(__GFP_DMA | __GFP_HIGHMEM)); -+ if (c) { -+ pte_t *pte = consistent_pte + CONSISTENT_OFFSET(c->vm_start); -+ struct page *end = page + (1 << order); -+ -+ c->vm_pages = page; -+ -+ /* -+ * Set the "dma handle" -+ */ -+ *handle = page_to_dma(dev, page); -+ -+ do { -+ BUG_ON(!pte_none(*pte)); -+ -+ /* -+ * x86 does not mark the pages reserved... -+ */ -+ SetPageReserved(page); -+ set_pte(pte, mk_pte(page, prot)); -+ page++; -+ pte++; -+ } while (size -= PAGE_SIZE); -+ -+ /* -+ * Free the otherwise unused pages. -+ */ -+ while (page < end) { -+ __free_page(page); -+ page++; -+ } -+ -+ return (void *)c->vm_start; -+ } -+ -+ if (page) -+ __free_pages(page, order); -+no_page: -+ *handle = ~0; -+ return NULL; -+} -+ -+/* -+ * Allocate DMA-coherent memory space and return both the kernel remapped -+ * virtual and bus address for that space. -+ */ -+void *dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t * handle, -+ gfp_t gfp) -+{ -+ return __dma_alloc(dev, size, handle, gfp, -+ pgprot_noncached(PAGE_KERNEL)); -+} -+ -+EXPORT_SYMBOL(dma_alloc_coherent); -+ -+/* -+ * Allocate a writecombining region, in much the same way as -+ * dma_alloc_coherent above. -+ */ -+void *dma_alloc_writecombine(struct device *dev, size_t size, -+ dma_addr_t * handle, gfp_t gfp) -+{ -+ return __dma_alloc(dev, size, handle, gfp, -+ pgprot_writecombine(PAGE_KERNEL)); -+} -+ -+EXPORT_SYMBOL(dma_alloc_writecombine); -+ -+static int dma_mmap(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t dma_addr, size_t size) -+{ -+ unsigned long flags, user_size, kern_size; -+ struct arch_vm_region *c; -+ int ret = -ENXIO; -+ -+ user_size = (vma->vm_end - vma->vm_start) >> PAGE_SHIFT; -+ -+ raw_spin_lock_irqsave(&consistent_lock, flags); -+ c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); -+ raw_spin_unlock_irqrestore(&consistent_lock, flags); -+ -+ if (c) { -+ unsigned long off = vma->vm_pgoff; -+ -+ kern_size = (c->vm_end - c->vm_start) >> PAGE_SHIFT; -+ -+ if (off < kern_size && user_size <= (kern_size - off)) { -+ vma->vm_flags |= VM_RESERVED; -+ ret = remap_pfn_range(vma, vma->vm_start, -+ page_to_pfn(c->vm_pages) + off, -+ user_size << PAGE_SHIFT, -+ vma->vm_page_prot); -+ } -+ } -+ -+ return ret; -+} -+ -+int dma_mmap_coherent(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t dma_addr, size_t size) -+{ -+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot); -+ return dma_mmap(dev, vma, cpu_addr, dma_addr, size); -+} -+ -+EXPORT_SYMBOL(dma_mmap_coherent); -+ -+int dma_mmap_writecombine(struct device *dev, struct vm_area_struct *vma, -+ void *cpu_addr, dma_addr_t dma_addr, size_t size) -+{ -+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+ return dma_mmap(dev, vma, cpu_addr, dma_addr, size); -+} -+ -+EXPORT_SYMBOL(dma_mmap_writecombine); -+ -+/* -+ * free a page as defined by the above mapping. -+ */ -+void dma_free_coherent(struct device *dev, size_t size, void *cpu_addr, -+ dma_addr_t handle) -+{ -+ struct arch_vm_region *c; -+ unsigned long flags, addr; -+ pte_t *ptep; -+ -+ size = PAGE_ALIGN(size); -+ -+ raw_spin_lock_irqsave(&consistent_lock, flags); -+ -+ c = vm_region_find(&consistent_head, (unsigned long)cpu_addr); -+ if (!c) -+ goto no_area; -+ -+ if ((c->vm_end - c->vm_start) != size) { -+ printk(KERN_ERR "%s: freeing wrong coherent size (%ld != %d)\n", -+ __func__, c->vm_end - c->vm_start, size); -+ dump_stack(); -+ size = c->vm_end - c->vm_start; -+ } -+ -+ ptep = consistent_pte + CONSISTENT_OFFSET(c->vm_start); -+ addr = c->vm_start; -+ do { -+ pte_t pte = ptep_get_and_clear(&init_mm, addr, ptep); -+ unsigned long pfn; -+ -+ ptep++; -+ addr += PAGE_SIZE; -+ -+ if (!pte_none(pte) && pte_present(pte)) { -+ pfn = pte_pfn(pte); -+ -+ if (pfn_valid(pfn)) { -+ struct page *page = pfn_to_page(pfn); -+ -+ /* -+ * x86 does not mark the pages reserved... -+ */ -+ ClearPageReserved(page); -+ -+ __free_page(page); -+ continue; -+ } -+ } -+ -+ printk(KERN_CRIT "%s: bad page in kernel page table\n", -+ __func__); -+ } while (size -= PAGE_SIZE); -+ -+ flush_tlb_kernel_range(c->vm_start, c->vm_end); -+ -+ list_del(&c->vm_list); -+ -+ raw_spin_unlock_irqrestore(&consistent_lock, flags); -+ -+ kfree(c); -+ return; -+ -+no_area: -+ raw_spin_unlock_irqrestore(&consistent_lock, flags); -+ printk(KERN_ERR "%s: trying to free invalid coherent area: %p\n", -+ __func__, cpu_addr); -+ dump_stack(); -+} -+ -+EXPORT_SYMBOL(dma_free_coherent); -+ -+/* -+ * Initialise the consistent memory allocation. -+ */ -+static int __init consistent_init(void) -+{ -+ pgd_t *pgd; -+ pmd_t *pmd; -+ pte_t *pte; -+ int ret = 0; -+ -+ do { -+ pgd = pgd_offset(&init_mm, CONSISTENT_BASE); -+ pmd = pmd_alloc(&init_mm, pgd, CONSISTENT_BASE); -+ if (!pmd) { -+ printk(KERN_ERR "%s: no pmd tables\n", __func__); -+ ret = -ENOMEM; -+ break; -+ } -+ /* The first level mapping may be created in somewhere. -+ * It's not necessary to warn here. */ -+ /* WARN_ON(!pmd_none(*pmd)); */ -+ -+ pte = pte_alloc_kernel(pmd, CONSISTENT_BASE); -+ if (!pte) { -+ ret = -ENOMEM; -+ break; -+ } -+ -+ consistent_pte = pte; -+ } while (0); -+ -+ return ret; -+} -+ -+core_initcall(consistent_init); -+ -+/* -+ * Make an area consistent for devices. -+ */ -+void consistent_sync(void *vaddr, size_t size, int direction) -+{ -+ unsigned long start = (unsigned long)vaddr; -+ unsigned long end = start + size; -+ -+ switch (direction) { -+ case DMA_FROM_DEVICE: /* invalidate only */ -+ cpu_dma_inval_range(start, end); -+ break; -+ case DMA_TO_DEVICE: /* writeback only */ -+ cpu_dma_wb_range(start, end); -+ break; -+ case DMA_BIDIRECTIONAL: /* writeback and invalidate */ -+ cpu_dma_wbinval_range(start, end); -+ break; -+ default: -+ BUG(); -+ } -+} -+ -+EXPORT_SYMBOL(consistent_sync); -diff -Nur linux-3.4.113.orig/arch/nds32/mm/extable.c linux-3.4.113/arch/nds32/mm/extable.c ---- linux-3.4.113.orig/arch/nds32/mm/extable.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/extable.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,18 @@ -+/* -+ * linux/arch/nds32/mm/extable.c -+ * -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+#include -+#include -+ -+int fixup_exception(struct pt_regs *regs) -+{ -+ const struct exception_table_entry *fixup; -+ -+ fixup = search_exception_tables(instruction_pointer(regs)); -+ if (fixup) -+ regs->NDS32_ipc = fixup->fixup; -+ -+ return fixup != NULL; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/mm/fault.c linux-3.4.113/arch/nds32/mm/fault.c ---- linux-3.4.113.orig/arch/nds32/mm/fault.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/fault.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,507 @@ -+/* -+ * linux/arch/arm/mm/fault.c -+ * -+ * Copyright (C) 1995 Linus Torvalds -+ * Modifications for ARM processor (c) 1995-2004 Russell King -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License version 2 as -+ * published by the Free Software Foundation. -+ */ -+/* ============================================================================ -+ * -+ * linux/arch/nds32/mm/fault.c -+ * -+ * Copyright (C) 2007 Andes Technology Corporation -+ * This file is part of Linux and should be licensed under the GPL. -+ * See the file COPYING for conditions for redistribution. -+ * -+ * Abstract: -+ * -+ * This program is for NDS32 architecture, referred from ARM's -+ * implementation. -+ * -+ * Revision History: -+ * -+ * Nov.26.2007 Initial ported by Tom, Shawn, and Steven, -+ * patched for KGDB and refined code by Harry. -+ * -+ * Note: -+ * -+ * ============================================================================ -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "fault.h" -+ -+/* -+ * This is useful to dump out the page tables associated with -+ * 'addr' in mm 'mm'. -+ */ -+void show_pte(struct mm_struct *mm, unsigned long addr) -+{ -+ pgd_t *pgd; -+ if (!mm) -+ mm = &init_mm; -+ -+ printk(KERN_ALERT "pgd = %p\n", mm->pgd); -+ pgd = pgd_offset(mm, addr); -+ printk(KERN_ALERT "[%08lx] *pgd=%08lx", addr, pgd_val(*pgd)); -+ -+ do { -+ pmd_t *pmd; -+ -+ if (pgd_none(*pgd)) -+ break; -+ -+ if (pgd_bad(*pgd)) { -+ printk("(bad)"); -+ break; -+ } -+ -+ pmd = pmd_offset(pgd, addr); -+#if PTRS_PER_PMD != 1 -+ printk(", *pmd=%08lx", pmd_val(*pmd)); -+#endif -+ -+ if (pmd_none(*pmd)) -+ break; -+ -+ if (pmd_bad(*pmd)) { -+ printk("(bad)"); -+ break; -+ } -+#ifndef CONFIG_HIGHMEM -+ { -+ pte_t *pte; -+ /* We must not map this if we have highmem enabled */ -+ pte = pte_offset_map(pmd, addr); -+ printk(", *pte=%08lx", pte_val(*pte)); -+ pte_unmap(pte); -+ } -+#endif -+ } while (0); -+ -+ printk("\n"); -+} -+ -+/* -+ * Oops. The kernel tried to access some page that wasn't present. -+ */ -+static void -+__do_kernel_fault(struct mm_struct *mm, unsigned long addr, unsigned int fsr, -+ struct pt_regs *regs) -+{ -+ /* -+ * Are we prepared to handle this kernel fault? -+ */ -+ if (fixup_exception(regs)) -+ return; -+ -+ /* -+ * No handler, we'll have to terminate things with extreme prejudice. -+ */ -+ bust_spinlocks(1); -+ printk(KERN_ALERT -+ "__do_kernel_fault: Unable to handle kernel %s at virtual address %08lx\n", -+ (addr < PAGE_SIZE) ? "NULL pointer dereference" : -+ "paging request", addr); -+ -+ show_pte(mm, addr); -+ die("Oops", regs, fsr); -+ bust_spinlocks(0); -+ do_exit(SIGKILL); -+} -+ -+/* -+ * Something tried to access memory that isn't in our memory map.. -+ * User mode accesses just cause a SIGSEGV -+ */ -+static void -+__do_user_fault(struct task_struct *tsk, unsigned long addr, -+ unsigned int fsr, int code, struct pt_regs *regs) -+{ -+ struct siginfo si; -+ -+#ifdef CONFIG_DEBUG_USER -+ if (user_debug & UDBG_SEGV) { -+ printk(KERN_DEBUG -+ "%s: unhandled page fault at 0x%08lx, code 0x%03x\n", -+ tsk->comm, addr, fsr); -+ show_pte(tsk->mm, addr); -+ show_regs(regs); -+ } -+#endif -+ -+ tsk->thread.address = addr; -+ tsk->thread.error_code = fsr; -+ tsk->thread.trap_no = 14; -+ si.si_signo = SIGSEGV; -+ si.si_errno = 0; -+ si.si_code = code; -+ si.si_addr = (void __user *)addr; -+ force_sig_info(SIGSEGV, &si, tsk); -+} -+ -+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs) -+{ -+ struct task_struct *tsk = current; -+ struct mm_struct *mm = tsk->active_mm; -+ -+ /* -+ * If we are in kernel mode at this point, we -+ * have no context to handle this fault with. -+ */ -+ if (user_mode(regs)) { -+ __do_user_fault(tsk, addr, fsr, SEGV_MAPERR, regs); -+ } else { -+ __do_kernel_fault(mm, addr, fsr, regs); -+ } -+} -+ -+#define VM_FAULT_BADMAP 0x010000 -+#define VM_FAULT_BADACCESS 0x020000 -+ -+void do_page_fault(unsigned long entry, unsigned long addr, -+ unsigned int error_code, struct pt_regs *regs) -+{ -+ struct task_struct *tsk; -+ struct mm_struct *mm; -+ struct vm_area_struct *vma; -+ siginfo_t info; -+ int fault; -+ unsigned int mask = VM_READ | VM_WRITE | VM_EXEC; -+ unsigned int flags = FAULT_FLAG_ALLOW_RETRY | FAULT_FLAG_KILLABLE; -+ -+ error_code = error_code & (ITYPE_mskINST | ITYPE_mskETYPE); -+ tsk = current; -+ mm = tsk->mm; -+ info.si_code = SEGV_MAPERR; -+ /* -+ * We fault-in kernel-space virtual memory on-demand. The -+ * 'reference' page table is init_mm.pgd. -+ * -+ * NOTE! We MUST NOT take any locks for this case. We may -+ * be in an interrupt or a critical region, and should -+ * only copy the information from the master page table, -+ * nothing more. -+ */ -+ if (addr >= TASK_SIZE) { -+ if (user_mode(regs)) -+ goto bad_area_nosemaphore; -+ -+ if (addr >= TASK_SIZE && addr < VMALLOC_END && (entry == 2)) -+ goto vmalloc_fault; -+ else -+ goto no_context; -+ } -+ -+ /* -+ * If we're in an interrupt or have no user -+ * context, we must not take the fault.. -+ */ -+ if (unlikely(in_atomic() || !mm)) -+ goto no_context; -+ -+ /* -+ * As per x86, we may deadlock here. However, since the kernel only -+ * validly references user space from well defined areas of the code, -+ * we can bug out early if this is from code which shouldn't. -+ */ -+ if (unlikely(!down_read_trylock(&mm->mmap_sem))) { -+ if (!user_mode(regs) && -+ !search_exception_tables(instruction_pointer(regs))) -+ goto no_context; -+retry: -+ down_read(&mm->mmap_sem); -+ } else { -+ /* -+ * The above down_read_trylock() might have succeeded in which -+ * case, we'll have missed the might_sleep() from down_read(). -+ */ -+ might_sleep(); -+#ifdef CONFIG_DEBUG_VM -+ if (!user_mode(regs) && -+ !search_exception_tables(instruction_pointer(regs))) -+ goto no_context; -+#endif -+ } -+ -+ vma = find_vma(mm, addr); -+ -+ if (unlikely(!vma)) -+ goto bad_area; -+ -+ if (vma->vm_start <= addr) -+ goto good_area; -+ -+ if (unlikely(!(vma->vm_flags & VM_GROWSDOWN))) -+ goto bad_area; -+ -+ if (unlikely(expand_stack(vma, addr))) -+ goto bad_area; -+ -+ /* -+ * Ok, we have a good vm_area for this memory access, so -+ * we can handle it.. -+ */ -+ -+good_area: -+ info.si_code = SEGV_ACCERR; -+ -+ /* first do some preliminary protection checks */ -+ if (entry == 2) { -+ if (error_code & ITYPE_mskINST) -+ mask = VM_EXEC; -+ else { -+ mask = VM_READ | VM_WRITE; -+ if (vma->vm_flags & VM_WRITE) -+ flags |= FAULT_FLAG_WRITE; -+ } -+ } else if (entry == 3) { -+ switch (error_code & ITYPE_mskETYPE) { -+ case RD_PROT: -+ mask = VM_READ; -+ break; -+ case WRT_PROT: -+ mask = VM_WRITE; -+ flags |= FAULT_FLAG_WRITE; -+ break; -+ case NOEXEC: -+ mask = VM_EXEC; -+ break; -+ case PAGE_MODIFY: -+ mask = VM_WRITE; -+ flags |= FAULT_FLAG_WRITE; -+ break; -+ case ACC_BIT: -+ BUG(); -+ default: -+ break; -+ } -+ -+ } -+ if (!(vma->vm_flags & mask)) -+ goto bad_area; -+ -+ /* -+ * If for any reason at all we couldn't handle the fault, -+ * make sure we exit gracefully rather than endlessly redo -+ * the fault. -+ */ -+ -+ fault = handle_mm_fault(mm, vma, addr, flags); -+ -+ /* -+ * If we need to retry but a fatal signal is pending, handle the -+ * signal first. We do not need to release the mmap_sem because it -+ * would already be released in __lock_page_or_retry in mm/filemap.c. -+ */ -+ if ((fault & VM_FAULT_RETRY) && fatal_signal_pending(current)) -+ return; -+ -+ if (unlikely(fault & VM_FAULT_ERROR)) { -+ if (fault & VM_FAULT_OOM) -+ goto out_of_memory; -+ else if (fault & VM_FAULT_SIGBUS) -+ goto do_sigbus; -+ BUG(); -+ } -+ -+ /* -+ * Major/minor page fault accounting is only done on the initial -+ * attempt. If we go through a retry, it is extremely likely that the -+ * page will be found in page cache at that point. -+ */ -+ if (flags & FAULT_FLAG_ALLOW_RETRY) { -+ if (fault & VM_FAULT_MAJOR) -+ tsk->maj_flt++; -+ else -+ tsk->min_flt++; -+ if (fault & VM_FAULT_RETRY) { -+ flags &= ~FAULT_FLAG_ALLOW_RETRY; -+ flags |= FAULT_FLAG_TRIED; -+ -+ /* No need to up_read(&mm->mmap_sem) as we would -+ * have already released it in __lock_page_or_retry -+ * in mm/filemap.c. -+ */ -+ goto retry; -+ } -+ } -+ -+ up_read(&mm->mmap_sem); -+ return; -+ -+ /* -+ * Something tried to access memory that isn't in our memory map.. -+ * Fix it, but check if it's kernel or user first.. -+ */ -+bad_area: -+ up_read(&mm->mmap_sem); -+ -+bad_area_nosemaphore: -+ -+ /* User mode accesses just cause a SIGSEGV */ -+ -+ if (user_mode(regs)) { -+ tsk->thread.address = addr; -+ tsk->thread.error_code = error_code; -+ tsk->thread.trap_no = 14; -+ info.si_signo = SIGSEGV; -+ info.si_errno = 0; -+ /* info.si_code has been set above */ -+ info.si_addr = (void *)addr; -+ force_sig_info(SIGSEGV, &info, tsk); -+ return; -+ } -+ -+no_context: -+ -+ /* Are we prepared to handle this kernel fault? -+ * -+ * (The kernel has valid exception-points in the source -+ * when it acesses user-memory. When it fails in one -+ * of those points, we find it in a table and do a jump -+ * to some fixup code that loads an appropriate error -+ * code) -+ */ -+ -+ { -+ const struct exception_table_entry *entry; -+ -+ if ((entry = -+ search_exception_tables(instruction_pointer(regs))) != -+ NULL) { -+ /* Adjust the instruction pointer in the stackframe */ -+ instruction_pointer(regs) = entry->fixup; -+ return; -+ } -+ } -+ -+ /* -+ * Oops. The kernel tried to access some bad page. We'll have to -+ * terminate things with extreme prejudice. -+ */ -+ -+ bust_spinlocks(1); -+ printk(KERN_ALERT -+ "Unable to handle kernel %s at virtual address %08lx\n", -+ (addr < PAGE_SIZE) ? "NULL pointer dereference" : -+ "paging request", addr); -+ -+ show_pte(mm, addr); -+ die("Oops", regs, error_code); -+ bust_spinlocks(0); -+ do_exit(SIGKILL); -+ -+ /* TODO: verify this necessity */ -+ return; -+ -+ /* -+ * We ran out of memory, or some other thing happened to us that made -+ * us unable to handle the page fault gracefully. -+ */ -+ -+out_of_memory: -+ up_read(&mm->mmap_sem); -+ if (!user_mode(regs)) -+ goto no_context; -+ pagefault_out_of_memory(); -+ return; -+ -+do_sigbus: -+ up_read(&mm->mmap_sem); -+ -+ /* Kernel mode? Handle exceptions or die */ -+ if (!user_mode(regs)) -+ goto no_context; -+ -+ /* -+ * Send a sigbus -+ */ -+ tsk->thread.address = addr; -+ tsk->thread.error_code = error_code; -+ tsk->thread.trap_no = 14; -+ info.si_signo = SIGBUS; -+ info.si_errno = 0; -+ info.si_code = BUS_ADRERR; -+ info.si_addr = (void *)addr; -+ force_sig_info(SIGBUS, &info, tsk); -+ -+ return; -+ -+vmalloc_fault: -+ { -+ /* -+ * Synchronize this task's top level page-table -+ * with the 'reference' page table. -+ * -+ * Use current_pgd instead of tsk->active_mm->pgd -+ * since the latter might be unavailable if this -+ * code is executed in a misfortunately run irq -+ * (like inside schedule() between switch_mm and -+ * switch_to...). -+ */ -+ -+ unsigned int index = pgd_index(addr); -+ pgd_t *pgd, *pgd_k; -+ pud_t *pud, *pud_k; -+ pmd_t *pmd, *pmd_k; -+ pte_t *pte_k; -+ -+ pgd = (pgd_t *) __va(GET_L1_PPTB()) + index; -+ pgd_k = init_mm.pgd + index; -+ -+ if (!pgd_present(*pgd_k)) -+ goto no_context; -+ -+ pud = pud_offset(pgd, addr); -+ pud_k = pud_offset(pgd_k, addr); -+ if (!pud_present(*pud_k)) -+ goto no_context; -+ -+ pmd = pmd_offset(pud, addr); -+ pmd_k = pmd_offset(pud_k, addr); -+ if (!pmd_present(*pmd_k)) -+ goto no_context; -+ -+ if (!pmd_present(*pmd)) { -+ set_pmd(pmd, *pmd_k); -+ /* TODO: need to do a cache flush like arm, -+ * maybe add at header file */ -+ } else -+ -+ BUG_ON(pmd_page(*pmd) != pmd_page(*pmd_k)); -+ -+ /* -+ * Since the vmalloc area is global, we don't -+ * need to copy individual PTE's, it is enough to -+ * copy the pgd pointer into the pte page of the -+ * root task. If that is there, we'll find our pte if -+ * it exists. -+ */ -+ -+ /* Make sure the actual PTE exists as well to -+ * catch kernel vmalloc-area accesses to non-mapped -+ * addres. If we don't do this, this will just -+ * silently loop forever. -+ */ -+ -+ pte_k = pte_offset_kernel(pmd_k, addr); -+ if (!pte_present(*pte_k)) -+ goto no_context; -+ -+ return; -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/mm/fault.h linux-3.4.113/arch/nds32/mm/fault.h ---- linux-3.4.113.orig/arch/nds32/mm/fault.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/fault.h 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,5 @@ -+void do_bad_area(unsigned long addr, unsigned int fsr, struct pt_regs *regs); -+ -+void show_pte(struct mm_struct *mm, unsigned long addr); -+ -+unsigned long search_exception_table(unsigned long addr); -diff -Nur linux-3.4.113.orig/arch/nds32/mm/highmem.c linux-3.4.113/arch/nds32/mm/highmem.c ---- linux-3.4.113.orig/arch/nds32/mm/highmem.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/highmem.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,76 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+void *kmap(struct page *page) -+{ -+ unsigned long vaddr; -+ might_sleep(); -+ if (!PageHighMem(page)) -+ return page_address(page); -+ vaddr = (unsigned long)kmap_high(page); -+ return (void *)vaddr; -+} -+ -+EXPORT_SYMBOL(kmap); -+ -+void kunmap(struct page *page) -+{ -+ BUG_ON(in_interrupt()); -+ if (!PageHighMem(page)) -+ return; -+ kunmap_high(page); -+} -+ -+EXPORT_SYMBOL(kunmap); -+ -+/* -+ * kmap_atomic/kunmap_atomic is significantly faster than kmap/kunmap because -+ * no global lock is needed and because the kmap code must perform a global TLB -+ * invalidation when the kmap pool wraps. -+ * -+ * However when holding an atomic kmap is is not legal to sleep, so atomic -+ * kmaps are appropriate for short, tight code paths only. -+ */ -+void *kmap_atomic(struct page *page) -+{ -+ unsigned int idx; -+ unsigned long vaddr, pte; -+ int type; -+ -+ pagefault_disable(); -+ if (!PageHighMem(page)) -+ return page_address(page); -+ -+ type = kmap_atomic_idx_push(); -+ -+ idx = type + KM_TYPE_NR * smp_processor_id(); -+ vaddr = __fix_to_virt(FIX_KMAP_BEGIN + idx); -+ pte = (page_to_pfn(page) << PAGE_SHIFT) | (PAGE_KERNEL); -+ asm volatile ("mtsr %0, $TLB_VPN\n\t" -+ "dsb\n\t" -+ "tlbop %1, RWLK\n\t" -+ "isb\n\t" -+ ::"r" (vaddr), "r"(pte)); -+ return (void *)vaddr; -+} -+ -+EXPORT_SYMBOL(kmap_atomic); -+ -+void __kunmap_atomic(void *kvaddr) -+{ -+ if (kvaddr >= (void *)FIXADDR_START) { -+ kmap_atomic_idx_pop(); -+ asm volatile ("tlbop %0, UNLK\n\t" -+ "tlbop %0, INV\n\t" -+ ::"r" (kvaddr)); -+ } -+ pagefault_enable(); -+} -+ -+EXPORT_SYMBOL(__kunmap_atomic); -diff -Nur linux-3.4.113.orig/arch/nds32/mm/init.c linux-3.4.113/arch/nds32/mm/init.c ---- linux-3.4.113.orig/arch/nds32/mm/init.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/init.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,438 @@ -+/* -+ * linux/arch/nds32/mm/init.c -+ * -+ * Copyright (C) 1995-2002 Russell King -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#include "mm.h" -+#include "../../kernel/signal.h" -+ -+#define TABLE_SIZE (PTRS_PER_PTE * sizeof(pte_t)) -+ -+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers); -+DEFINE_SPINLOCK(anon_alias_lock); -+extern pgd_t swapper_pg_dir[PTRS_PER_PGD]; -+extern unsigned long phys_initrd_start; -+extern unsigned long phys_initrd_size; -+ -+/* -+ * empty_zero_page is a special page that is used for -+ * zero-initialized data and COW. -+ */ -+struct page *empty_zero_page; -+ -+void show_mem(unsigned int flags) -+{ -+ int free = 0, total = 0, reserved = 0; -+ int shared = 0, cached = 0, slab = 0, node; -+ -+ printk("Mem-info:\n"); -+ show_free_areas(flags); -+ printk("Free swap: %6ldkB\n", nr_swap_pages << (PAGE_SHIFT - 10)); -+ -+ for_each_online_node(node) { -+ struct page *page, *end; -+ -+ page = NODE_MEM_MAP(node); -+ end = page + NODE_DATA(node)->node_spanned_pages; -+ -+ do { -+ total++; -+ if (PageReserved(page)) -+ reserved++; -+ else if (PageSwapCache(page)) -+ cached++; -+ else if (PageSlab(page)) -+ slab++; -+ else if (!page_count(page)) -+ free++; -+ else -+ shared += page_count(page) - 1; -+ page++; -+ } while (page < end); -+ } -+ -+ printk("%d pages of RAM\n", total); -+ printk("%d free pages\n", free); -+ printk("%d reserved pages\n", reserved); -+ printk("%d slab pages\n", slab); -+ printk("%d pages shared\n", shared); -+ printk("%d pages swap cached\n", cached); -+} -+ -+struct node_info { -+ unsigned int start; -+ unsigned int end; -+ int bootmap_pages; -+}; -+ -+#define O_PFN_DOWN(x) ((x) >> PAGE_SHIFT) -+#define V_PFN_DOWN(x) O_PFN_DOWN(__pa(x)) -+ -+#define O_PFN_UP(x) (PAGE_ALIGN(x) >> PAGE_SHIFT) -+#define V_PFN_UP(x) O_PFN_UP(__pa(x)) -+ -+#define PFN_SIZE(x) ((x) >> PAGE_SHIFT) -+#define PFN_RANGE(s,e) PFN_SIZE(PAGE_ALIGN((unsigned long)(e)) - \ -+ (((unsigned long)(s)) & PAGE_MASK)) -+#ifdef CONFIG_EARLY_PRINTK -+#include -+ -+/* -+ * Using tlbop to create an early I/O mapping -+ */ -+void __iomem *__init early_io_map(phys_addr_t pa) -+{ -+ unsigned long va; -+ pa &= PAGE_MASK; -+ pa += pgprot_val(PAGE_DEVICE); -+ va = fix_to_virt(FIX_EARLY_DEBUG); -+ /* insert and lock this page to tlb entry directly */ -+ asm volatile ("mtsr %0, $TLB_VPN\n\t" -+ "dsb\n\t" -+ "tlbop %1, RWLK\n\t" "isb\n\t"::"r" (va), "r"(pa)); -+ return (void __iomem *)va; -+} -+ -+int __init early_io_unmap(void) -+{ -+ unsigned long va; -+ va = fix_to_virt(FIX_EARLY_DEBUG); -+ asm volatile ("tlbop %0, UNLK\n\t" -+ "tlbop %0, INV\n\t" "isb\n\t"::"r" (va)); -+ return 0; -+} -+ -+late_initcall(early_io_unmap); -+#endif -+ -+static void __init zone_sizes_init(void) -+{ -+ unsigned long zones_size[MAX_NR_ZONES]; -+ -+ /* Clear the zone sizes */ -+ memset(zones_size, 0, sizeof(zones_size)); -+ -+ zones_size[ZONE_NORMAL] = max_low_pfn; -+#ifdef CONFIG_HIGHMEM -+ zones_size[ZONE_HIGHMEM] = max_pfn; -+#endif -+ free_area_init_nodes(zones_size); -+ -+} -+ -+/* -+ * Map all physical memory under high_memory into kernel's address space. -+ * -+ * This is explicitly coded for two-level page tables, so if you need -+ * something else then this needs to change. -+ */ -+static void __init map_ram(void) -+{ -+ unsigned long v, p, e; -+ pgd_t *pge; -+ pud_t *pue; -+ pmd_t *pme; -+ pte_t *pte; -+ /* These mark extents of read-only kernel pages... -+ * ...from vmlinux.lds.S -+ */ -+ -+ p = (u32) memblock_start_of_DRAM() & PAGE_MASK; -+ e = min((u32) memblock_end_of_DRAM(), (u32) __pa(high_memory)); -+ -+ v = (u32) __va(p); -+ pge = pgd_offset_k(v); -+ -+ while (p < e) { -+ int j; -+ pue = pud_offset(pge, v); -+ pme = pmd_offset(pue, v); -+ -+ if ((u32) pue != (u32) pge || (u32) pme != (u32) pge) { -+ panic("%s: Kernel hardcoded for " -+ "two-level page tables", __func__); -+ } -+ -+ /* Alloc one page for holding PTE's... */ -+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); -+ set_pmd(pme, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); -+ -+ /* Fill the newly allocated page with PTE'S */ -+ for (j = 0; p < e && j < PTRS_PER_PTE; -+ v += PAGE_SIZE, p += PAGE_SIZE, j++, pte++) { -+ /* Create mapping between p and v. */ -+ /* TODO: more fine grant for page access permission */ -+ set_pte(pte, __pte(p + pgprot_val(PAGE_KERNEL))); -+ } -+ -+ pge++; -+ } -+} -+ -+static void __init fixedrange_init(void) -+{ -+ unsigned long vaddr, phys, prot; -+ pgd_t *pgd; -+ pud_t *pud; -+ pmd_t *pmd; -+ pte_t *pte; -+ -+ /* -+ * Fixed mappings: -+ */ -+ vaddr = __fix_to_virt(__end_of_fixed_addresses - 1); -+ pgd = swapper_pg_dir + pgd_index(vaddr); -+ pud = pud_offset(pgd, vaddr); -+ pmd = pmd_offset(pud, vaddr); -+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); -+ set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); -+ -+ /* create return_syscall mapping. */ -+ vaddr = __fix_to_virt(FIX_RETURN_SYSCALL); -+ phys = RETURN_SYSCALL_PA_BASE; -+ prot = PAGE_UXKRWX_V2; -+ pte = pte_offset_kernel(pmd, vaddr); -+ set_pte(pte, pfn_pte(phys >> PAGE_SHIFT, prot)); -+ -+#ifdef CONFIG_HIGHMEM -+ /* -+ * Permanent kmaps: -+ */ -+ vaddr = PKMAP_BASE; -+ -+ pgd = swapper_pg_dir + pgd_index(vaddr); -+ pud = pud_offset(pgd, vaddr); -+ pmd = pmd_offset(pud, vaddr); -+ pte = (pte_t *) alloc_bootmem_low_pages(PAGE_SIZE); -+ set_pmd(pmd, __pmd(__pa(pte) + _PAGE_KERNEL_TABLE)); -+ pkmap_page_table = pte; -+#endif /* CONFIG_HIGHMEM */ -+} -+ -+/* -+ * paging_init() sets up the page tables, initialises the zone memory -+ * maps, and sets up the zero page, bad page and bad page tables. -+ */ -+void __init paging_init(struct machine_desc *mdesc) -+{ -+ void *zero_page; -+ int i; -+ -+ printk(KERN_INFO "Setting up paging and PTEs.\n"); -+ -+#ifdef CONFIG_BLK_DEV_INITRD -+ if (phys_initrd_size) { -+ /* assume initrd is put on node 0 */ -+ reserve_bootmem_node(NODE_DATA(0), phys_initrd_start, -+ phys_initrd_size, BOOTMEM_DEFAULT); -+ initrd_start = __phys_to_virt(phys_initrd_start); -+ initrd_end = initrd_start + phys_initrd_size; -+ printk(KERN_INFO -+ "initrd_start at 0x%08lx, initrd_end at 0x%08lx\n", -+ initrd_start, initrd_end); -+ } -+#endif -+ -+ /* clear out the init_mm.pgd that will contain the kernel's mappings */ -+ for (i = 0; i < PTRS_PER_PGD; i++) -+ swapper_pg_dir[i] = __pgd(1); -+ -+ map_ram(); -+ -+ if (mdesc->map_io) -+ mdesc->map_io(); -+ -+ fixedrange_init(); -+ -+ /* allocate space for empty_zero_page */ -+ zero_page = alloc_bootmem_low_pages(PAGE_SIZE); -+ memset(zero_page, 0, PAGE_SIZE); -+ -+ zone_sizes_init(); -+ -+ empty_zero_page = virt_to_page(zero_page); -+#ifdef CONFIG_NO_KERNEL_LARGE_PAGE -+ SET_MMU_CTL(GET_MMU_CTL() & ~0x400); -+#endif -+#ifdef CONFIG_SMP -+ cpu_dcache_wbinval_all(); -+#endif -+ flush_dcache_page(empty_zero_page); -+} -+ -+static inline int free_area(unsigned long addr, unsigned long end, char *s) -+{ -+ unsigned int size = (end - addr) >> 10; -+ int pages = 0; -+ -+ for (; addr < end; addr += PAGE_SIZE) { -+ struct page *page = virt_to_page(addr); -+ ClearPageReserved(page); -+ init_page_count(page); -+ free_page(addr); -+ totalram_pages++; -+ pages++; -+ } -+ -+ if (size && s) -+ printk(KERN_INFO "free_area: Freeing %s memory: %dK\n", s, -+ size); -+ -+ return pages; -+} -+ -+/* Free the reserved page into the buddy system, so it gets managed. */ -+static inline void __free_reserved_page(struct page *page) -+{ -+ ClearPageReserved(page); -+ init_page_count(page); -+ __free_page(page); -+} -+ -+#ifdef CONFIG_HIGHMEM -+void free_highmem_page(struct page *page) -+{ -+ __free_reserved_page(page); -+ totalram_pages++; -+ totalhigh_pages++; -+} -+#endif -+ -+static inline void __init free_highmem(void) -+{ -+#ifdef CONFIG_HIGHMEM -+ unsigned long pfn; -+ for (pfn = PFN_UP(__pa(high_memory)); pfn < max_pfn; pfn++) { -+ phys_addr_t paddr = (phys_addr_t) pfn << PAGE_SHIFT; -+ if (!memblock_is_reserved(paddr)) -+ free_highmem_page(pfn_to_page(pfn)); -+ } -+#endif -+} -+ -+static void __init set_max_mapnr_init(void) -+{ -+ max_mapnr = max_pfn; -+} -+ -+/* -+ * mem_init() marks the free areas in the mem_map and tells us how much -+ * memory is free. This is done after various parts of the system have -+ * claimed their memory after the kernel image. -+ */ -+void __init mem_init(void) -+{ -+ phys_addr_t memory_start = memblock_start_of_DRAM(); -+ BUG_ON(!mem_map); -+ set_max_mapnr_init(); -+ -+ free_highmem(); -+ -+ /* this will put all low memory onto the freelists */ -+ totalram_pages += free_all_bootmem(); -+ -+ printk(KERN_INFO "virtual kernel memory layout:\n" -+ " fixmap : 0x%08lx - 0x%08lx (%4ld kB)\n" -+#ifdef CONFIG_HIGHMEM -+ " pkmap : 0x%08lx - 0x%08lx (%4ld kB)\n" -+#endif -+ " consist : 0x%08lx - 0x%08lx (%4ld MB)\n" -+ " vmalloc : 0x%08lx - 0x%08lx (%4ld MB)\n" -+ " lowmem : 0x%08lx - 0x%08lx (%4ld MB)\n" -+ " .init : 0x%08lx - 0x%08lx (%4ld kB)\n" -+ " .data : 0x%08lx - 0x%08lx (%4ld kB)\n" -+ " .text : 0x%08lx - 0x%08lx (%4ld kB)\n", -+ FIXADDR_START, FIXADDR_TOP, (FIXADDR_TOP - FIXADDR_START) >> 10, -+#ifdef CONFIG_HIGHMEM -+ PKMAP_BASE, PKMAP_BASE + LAST_PKMAP * PAGE_SIZE, -+ (LAST_PKMAP * PAGE_SIZE) >> 10, -+#endif -+ CONSISTENT_BASE, CONSISTENT_END, -+ ((CONSISTENT_END) - (CONSISTENT_BASE)) >> 20, VMALLOC_START, -+ (unsigned long)VMALLOC_END, (VMALLOC_END - VMALLOC_START) >> 20, -+ (unsigned long)__va(memory_start), (unsigned long)high_memory, -+ ((unsigned long)high_memory - -+ (unsigned long)__va(memory_start)) >> 20, -+ (unsigned long)&__init_begin, (unsigned long)&__init_end, -+ ((unsigned long)&__init_end - -+ (unsigned long)&__init_begin) >> 10, (unsigned long)&_etext, -+ (unsigned long)&_edata, -+ ((unsigned long)&_edata - (unsigned long)&_etext) >> 10, -+ (unsigned long)&_text, (unsigned long)&_etext, -+ ((unsigned long)&_etext - (unsigned long)&_text) >> 10); -+ -+ /* -+ * Check boundaries twice: Some fundamental inconsistencies can -+ * be detected at build time already. -+ */ -+#define __FIXADDR_TOP (-PAGE_SIZE) -+#ifdef CONFIG_HIGHMEM -+ BUILD_BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START); -+ BUILD_BUG_ON((CONSISTENT_END) > PKMAP_BASE); -+#endif -+ BUILD_BUG_ON(VMALLOC_END > CONSISTENT_BASE); -+#define high_memory (-128UL << 20) -+ BUILD_BUG_ON(VMALLOC_START >= VMALLOC_END); -+#undef high_memory -+#undef __FIXADDR_TOP -+ -+#ifdef CONFIG_HIGHMEM -+ BUG_ON(PKMAP_BASE + LAST_PKMAP * PAGE_SIZE > FIXADDR_START); -+ BUG_ON(CONSISTENT_END > PKMAP_BASE); -+#endif -+ BUG_ON(VMALLOC_END > CONSISTENT_BASE); -+ BUG_ON(VMALLOC_START >= VMALLOC_END); -+ BUG_ON((unsigned long)high_memory > VMALLOC_START); -+ -+ return; -+} -+ -+void free_initmem(void) -+{ -+ free_area((unsigned long)(&__init_begin), -+ (unsigned long)(&__init_end), "init"); -+} -+ -+#ifdef CONFIG_BLK_DEV_INITRD -+static int keep_initrd; -+ -+void free_initrd_mem(unsigned long start, unsigned long end) -+{ -+ if (!keep_initrd) -+ free_area(start, end, "initrd"); -+} -+ -+static int __init keepinitrd_setup(char *__unused) -+{ -+ keep_initrd = 1; -+ return 1; -+} -+ -+__setup("keepinitrd", keepinitrd_setup); -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/mm/ioremap.c linux-3.4.113/arch/nds32/mm/ioremap.c ---- linux-3.4.113.orig/arch/nds32/mm/ioremap.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/ioremap.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,89 @@ -+/* -+ * linux/arch/nds32/mm/ioremap.c -+ * -+ * Re-map IO memory to kernel address space so that we can access it. -+ * -+ * (C) Copyright 1995 1996 Linus Torvalds -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * Hacked for ARM by Phil Blundell -+ * Hacked to allow all architectures to build, and various cleanups -+ * by Russell King -+ * -+ * This allows a driver to remap an arbitrary region of bus memory into -+ * virtual space. One should *only* use readl, writel, memcpy_toio and -+ * so on with such remapped areas. -+ * -+ * Because the ARM only has a 32-bit address space we can't address the -+ * whole of the (physical) PCI space at once. PCI huge-mode addressing -+ * allows us to circumvent this restriction by splitting PCI space into -+ * two 2GB chunks and mapping only one at a time into processor memory. -+ * We use MMU protection domains to trap any attempt to access the bank -+ * that is not currently mapped. (This isn't fully implemented yet.) -+ */ -+#include -+#include -+#include -+#include -+ -+/* -+ * Remap an arbitrary physical address space into the kernel virtual -+ * address space. Needed when the kernel wants to access high addresses -+ * directly. -+ * -+ * NOTE! We need to allow non-page-aligned mappings too: we will obviously -+ * have to convert them into an offset in a page-aligned mapping, but the -+ * caller shouldn't need to know that small detail. -+ * -+ * 'flags' are the extra L_PTE_ flags that you want to specify for this -+ * mapping. See include/asm-arm/proc-armv/pgtable.h for more information. -+ */ -+void __iomem *__ioremap(unsigned long phys_addr, size_t size, -+ unsigned long flags, unsigned long align) -+{ -+ struct vm_struct *area; -+ unsigned long addr, offset, last_addr; -+ pgprot_t prot; -+ -+ /* Don't allow wraparound or zero size */ -+ last_addr = phys_addr + size - 1; -+ if (!size || last_addr < phys_addr) -+ return NULL; -+ -+ /* -+ * Mappings have to be page-aligned -+ */ -+ offset = phys_addr & ~PAGE_MASK; -+ phys_addr &= PAGE_MASK; -+ size = PAGE_ALIGN(last_addr + 1) - phys_addr; -+ -+ /* -+ * Ok, go for it.. -+ */ -+ area = get_vm_area(size, VM_IOREMAP); -+ if (!area) -+ return NULL; -+ -+ area->phys_addr = phys_addr; -+ addr = (unsigned long)area->addr; -+ /* TODO: verify this value for ioremap */ -+ prot = __pgprot(_PAGE_V | _PAGE_M_KRW | _PAGE_D | -+ _PAGE_G | _PAGE_C_DEV | flags); -+ /* TODO: verify this use generic ioremap_page_range instead of -+ * self's remap_area_pages */ -+ if (ioremap_page_range(addr, addr + size, phys_addr, prot)) { -+ vunmap((void *)addr); -+ return NULL; -+ } -+ return (__force void __iomem *)(offset + (char *)addr); -+ -+} -+ -+EXPORT_SYMBOL(__ioremap); -+ -+void __iounmap(void __iomem * addr) -+{ -+ vunmap((void *)(PAGE_MASK & (unsigned long)addr)); -+} -+ -+EXPORT_SYMBOL(__iounmap); -diff -Nur linux-3.4.113.orig/arch/nds32/mm/Makefile linux-3.4.113/arch/nds32/mm/Makefile ---- linux-3.4.113.orig/arch/nds32/mm/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/Makefile 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,24 @@ -+# -+# Makefile for the linux arm-specific parts of the memory manager. -+# -+ -+obj-y := consistent.o extable.o \ -+ fault.o init.o ioremap.o mmap.o \ -+ mm-nds32.o cacheflush.o -+ -+obj-y += proc-n12.o -+obj-$(CONFIG_CCTL) += cctl.o -+obj-$(CONFIG_ALIGNMENT_TRAP) += alignment.o -+ifneq ($(CONFIG_CPU_NO_CONTEXT_ID), y) -+obj-y += tlb.o -+endif -+gcc_ver :=$(shell $(CC) -E -dM -xc /dev/null | grep __VERSION__ | sed 's/\#define __VERSION__ //') -+ifeq ($(shell expr `echo $(gcc_ver)` \>= 4.9.2 ), 1) -+CFLAGS_proc-n12.o += -fomit-frame-pointer -+else -+CFLAGS_proc-n12.o += -fomit-frame-pointer -mno-16bit -+endif -+obj-$(CONFIG_HIGHMEM) += highmem.o -+ifdef CONFIG_FUNCTION_TRACER -+CFLAGS_REMOVE_proc-n12.o = -pg -+endif -diff -Nur linux-3.4.113.orig/arch/nds32/mm/mmap.c linux-3.4.113/arch/nds32/mm/mmap.c ---- linux-3.4.113.orig/arch/nds32/mm/mmap.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/mmap.c 2016-12-01 20:59:24.368613368 +0100 -@@ -0,0 +1,101 @@ -+/* -+ * linux/arch/nds32/mm/mmap.c -+ * -+ * Copyright (C) 2009 Andes Technology Corporation -+ */ -+#include -+#include -+#include -+ -+#define COLOUR_ALIGN(addr,pgoff) \ -+ ((((addr)+REALSHMLBA-1)&~(REALSHMLBA-1)) + \ -+ (((pgoff)<mm; -+ struct vm_area_struct *vma; -+ unsigned long start_addr; -+ int do_align = 0; -+#ifdef CONFIG_CPU_CACHE_NONALIASING -+ int aliasing = 0; -+#else -+ int aliasing = 1; -+#endif -+ -+ /* -+ * We only need to do colour alignment if either the I or D -+ * caches alias. -+ */ -+ if (aliasing) -+ do_align = filp || (flags & MAP_SHARED); -+ -+ /* -+ * We should enforce the MAP_FIXED case. However, currently -+ * the generic kernel code doesn't allow us to handle this. -+ */ -+ if (flags & MAP_FIXED) { -+ if (aliasing && flags & MAP_SHARED && addr & (REALSHMLBA - 1)) -+ return -EINVAL; -+ return addr; -+ } -+ -+ if (len > TASK_SIZE) -+ return -ENOMEM; -+ -+ if (addr) { -+ if (do_align) -+ addr = COLOUR_ALIGN(addr, pgoff); -+ else -+ addr = PAGE_ALIGN(addr); -+ -+ vma = find_vma(mm, addr); -+ if (TASK_SIZE - len >= addr && -+ (!vma || addr + len <= vma->vm_start)) -+ return addr; -+ } -+ start_addr = addr = mm->free_area_cache; -+ -+full_search: -+ if (do_align) -+ addr = COLOUR_ALIGN(addr, pgoff); -+ else -+ addr = PAGE_ALIGN(addr); -+ -+ for (vma = find_vma(mm, addr);; vma = vma->vm_next) { -+ /* At this point: (!vma || addr < vma->vm_end). */ -+ if (TASK_SIZE - len < addr) { -+ /* -+ * Start a new search - just in case we missed -+ * some holes. -+ */ -+ if (start_addr != TASK_UNMAPPED_BASE) { -+ start_addr = addr = TASK_UNMAPPED_BASE; -+ goto full_search; -+ } -+ return -ENOMEM; -+ } -+ if (!vma || addr + len <= vma->vm_start) { -+ /* -+ * Remember the place where we stopped the search: -+ */ -+ mm->free_area_cache = addr + len; -+ return addr; -+ } -+ addr = vma->vm_end; -+ if (do_align) -+ addr = COLOUR_ALIGN(addr, pgoff); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/mm/mm.h linux-3.4.113/arch/nds32/mm/mm.h ---- linux-3.4.113.orig/arch/nds32/mm/mm.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/mm.h 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,19 @@ -+/* the upper-most page table pointer */ -+ -+#ifdef CONFIG_MMU -+ -+extern pmd_t *top_pmd; -+ -+#define TOP_PTE(x) pte_offset_kernel(top_pmd, x) -+ -+static inline pmd_t *pmd_off(pgd_t *pgd, unsigned long virt) -+{ -+ return pmd_offset(pgd, virt); -+} -+ -+static inline pmd_t *pmd_off_k(unsigned long virt) -+{ -+ return pmd_off(pgd_offset_k(virt), virt); -+} -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/mm/mm-nds32.c linux-3.4.113/arch/nds32/mm/mm-nds32.c ---- linux-3.4.113.orig/arch/nds32/mm/mm-nds32.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/mm-nds32.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,267 @@ -+/* -+ * linux/arch/nds32/mm/mm-nds32.c -+ * -+ * Copyright (C) 1998-2002 Russell King -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * Page table sludge for Andes N10/N12 processor architectures. -+ */ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include "./../kernel/signal.h" -+ -+extern void _text, _stext, _etext; -+extern void *high_memory; -+ -+#define FIRST_KERNEL_PGD_NR (USER_PTRS_PER_PGD) -+ -+/* -+ * need to get a 4k page for level 1 -+ */ -+ -+pgd_t *get_pgd_slow(struct mm_struct *mm) -+{ -+ pgd_t *new_pgd, *init_pgd; -+ int i; -+ -+ new_pgd = (pgd_t *) __get_free_pages(GFP_KERNEL, 0); //M order 0: one page -+ if (!new_pgd) -+ return NULL; -+ for (i = 0; i < PTRS_PER_PGD; i++) { -+ (*new_pgd) = 1; -+ new_pgd++; -+ } -+ new_pgd -= PTRS_PER_PGD; -+ -+ init_pgd = pgd_offset_k(0); -+ -+ memcpy(new_pgd + FIRST_KERNEL_PGD_NR, init_pgd + FIRST_KERNEL_PGD_NR, -+ (PTRS_PER_PGD - FIRST_KERNEL_PGD_NR) * sizeof(pgd_t)); -+ -+ cpu_dcache_wb_range((unsigned long)new_pgd, -+ (unsigned long)new_pgd + -+ PTRS_PER_PGD * sizeof(pgd_t)); -+ inc_zone_page_state(virt_to_page((unsigned long *)new_pgd), -+ NR_PAGETABLE); -+ -+ return new_pgd; -+} -+ -+void free_pgd_slow(struct mm_struct *mm, pgd_t * pgd) -+{ -+ pmd_t *pmd; -+ struct page *pte; -+ -+ if (!pgd) -+ return; -+ -+ pmd = (pmd_t *) pgd; -+ if (pmd_none(*pmd)) -+ goto free; -+ if (pmd_bad(*pmd)) { -+ pmd_ERROR(*pmd); -+ pmd_clear(pmd); -+ goto free; -+ } -+ -+ pte = pmd_page(*pmd); -+ pmd_clear(pmd); -+ dec_zone_page_state(virt_to_page((unsigned long *)pgd), NR_PAGETABLE); -+ pte_free(mm, pte); -+ pmd_free(mm, pmd); -+free: -+ free_pages((unsigned long)pgd, 0); -+} -+ -+/* -+ * Add a PAGE mapping between VIRT and PHYS in domain -+ * DOMAIN with protection PROT. Note that due to the -+ * way we map the PTEs, we must allocate two PTE_SIZE'd -+ * blocks - one for the Linux pte table, and one for -+ * the hardware pte table. -+ */ -+static inline void -+alloc_init_page(unsigned long virt, unsigned long phys, unsigned int prot_l1, -+ pgprot_t prot) -+{ -+ pmd_t *pmdp; -+ pte_t *ptep; -+ -+ pmdp = pmd_offset(pgd_offset_k(virt), virt); //L1PTE -+ if (pmd_none(*pmdp)) { //must not or 0xc0000000 -+ ptep = alloc_bootmem_low_pages(PTRS_PER_PTE * sizeof(pte_t)); -+ set_pmd(pmdp, __mk_pmd(ptep, 0)); -+ } -+ ptep = pte_offset_kernel(pmdp, virt); //L2PTE -+ set_pte(ptep, pfn_pte(phys >> PAGE_SHIFT, prot)); -+} -+ -+/* -+ * Clear any PGD mapping. On a two-level page table system, -+ * the clearance is done by the middle-level functions (pmd) -+ * rather than the top-level (pgd) functions. -+ */ -+static inline void clear_mapping(unsigned long virt) -+{ -+ pmd_clear(pmd_offset(pgd_offset_k(virt), virt)); -+} -+ -+struct mem_types { -+ unsigned int prot_pte; -+ unsigned int prot_l1; -+}; -+ -+static struct mem_types mem_types[] __initdata = { -+ [MT_DEVICE] = { -+ .prot_pte = 0x9f, //_KERNPG_TABLE, -+ .prot_l1 = PMD_TYPE_TABLE, -+ }, -+ [MT_CACHECLEAN] = { -+ .prot_l1 = PMD_TYPE_TABLE, -+ .prot_pte = 0x0, //_KERNPG_TABLE, -+ }, -+ [MT_MINICLEAN] = { -+ .prot_l1 = PMD_TYPE_TABLE, -+ .prot_pte = 0x0, // _KERNPG_TABLE, -+ }, -+ [MT_CACHE_L1] = { -+ .prot_pte = PAGE_CACHE_L1, -+ .prot_l1 = PMD_TYPE_TABLE, -+ }, -+ [MT_UXKRWX_V1] = { -+ .prot_pte = PAGE_UXKRWX_V1, -+ .prot_l1 = PMD_TYPE_TABLE, -+ }, -+ [MT_UXKRWX_V2] = { -+ .prot_pte = PAGE_UXKRWX_V2, -+ .prot_l1 = PMD_TYPE_TABLE, -+ }, -+ [MT_MEMORY] = { -+ .prot_pte = PAGE_MEMORY, -+ .prot_l1 = PMD_TYPE_TABLE, -+ }, -+ [MT_ROM] = { -+ .prot_l1 = PMD_TYPE_TABLE, -+ .prot_pte = 0x2bb, // _KERNPG_TABLE, -+ }, -+ [MT_ILM] = { -+ .prot_l1 = PMD_TYPE_TABLE, -+ .prot_pte = 0x2b7, // _KERNPG_TABLE, -+ }, -+ [MT_DLM] = { -+ .prot_l1 = PMD_TYPE_TABLE, -+ .prot_pte = 0x297, // _KERNPG_TABLE, -+ } -+}; -+ -+/* -+ * Create the page directory entries and any necessary -+ * page tables for the mapping specified by `md'. We -+ * are able to cope here with varying sizes and address -+ * offsets, and we take full advantage of sections. -+ */ -+static void __init create_mapping(struct map_desc *md) -+{ -+ unsigned long virt, length; -+ int prot_l1; -+ pgprot_t prot_pte; -+ long off; -+ -+ printk("virt:0x%08lx,phys:%08lx,size:%08lx,pte:%08x\n", -+ md->virtual, md->physical, md->length, -+ __pgprot(mem_types[md->type].prot_pte)); -+ -+ if (md->virtual < TASK_SIZE) { -+ printk(KERN_WARNING "BUG: not creating mapping area for " -+ "0x%08lx at 0x%08lx in user region, next frame\n", -+ md->physical, md->virtual); -+ panic("In :%s, line:%d", __func__, __LINE__); -+ return; -+ } -+ -+ if ((md->type == MT_DEVICE || md->type == MT_ROM) && -+ md->virtual >= PAGE_OFFSET && md->virtual < VMALLOC_END) { -+ printk(KERN_WARNING "BUG: mapping area for 0x%08lx at 0x%08lx " -+ "overlaps vmalloc space, next frame\n", -+ md->physical, md->virtual); -+ panic("In :%s, line:%d", __func__, __LINE__); -+ } -+ -+ prot_pte = __pgprot(mem_types[md->type].prot_pte); -+ prot_l1 = mem_types[md->type].prot_l1; -+ virt = md->virtual; -+ off = md->physical - virt; -+ -+ length = md->length; -+ if (mem_types[md->type].prot_l1 == 1 && -+ (virt & 0xfffff || (virt + off) & 0xfffff -+ || (virt + length) & 0xfffff)) { -+ printk(KERN_WARNING -+ "BUG: map area for 0x%08lx at 0x%08lx can not " -+ "be mapped using pages, ignoring. next frame\n", -+ md->physical, md->virtual); -+ panic("In :%s, line:%d", __func__, __LINE__); -+ return; -+ } -+ -+ while (length >= PAGE_SIZE) { -+#ifdef CONFIG_SMP -+ if (((virt >= (unsigned long)&_text) -+ && (virt < (unsigned long)&_etext)) -+ || ((virt >= 0xc0000000) && (virt < 0xc0008000))) -+ prot_pte = __pgprot(mem_types[MT_CACHE_L1].prot_pte); -+#endif -+ alloc_init_page(virt, virt + off, prot_l1, prot_pte); -+ virt += PAGE_SIZE; -+ length -= PAGE_SIZE; -+ } -+} -+ -+/* -+ * In order to soft-boot, we need to insert a 1:1 mapping in place of -+ * the user-mode pages. This will then ensure that we have predictable -+ * results when turning the mmu off -+ */ -+void setup_mm_for_reboot(char mode) -+{ -+ unsigned long pmdval; -+ pgd_t *pgd; -+ pmd_t *pmd; -+ int i; -+ -+ if (current->mm && current->mm->pgd) -+ pgd = current->mm->pgd; -+ else -+ pgd = init_mm.pgd; -+ -+ for (i = 0; i < USER_PTRS_PER_PGD; i++) { -+ pmdval = (i << PGDIR_SHIFT); -+ pmd = pmd_offset(pgd + i, i << PGDIR_SHIFT); -+ set_pmd(pmd, __pmd(pmdval)); -+ } -+} -+ -+/* -+ * Create the architecture specific mappings -+ */ -+void __init iotable_init(struct map_desc *io_desc, int nr) -+{ -+ int i; -+ -+ for (i = 0; i < nr; i++) { -+ create_mapping(io_desc + i); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/mm/proc-n12.c linux-3.4.113/arch/nds32/mm/proc-n12.c ---- linux-3.4.113.orig/arch/nds32/mm/proc-n12.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/proc-n12.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,845 @@ -+/* -+ * linux/arch/nds32/mm/proc-nds32.c -+ * -+ * Copyright (C) 2006 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * -+ * These are the low level assembler for performing cache and TLB -+ * functions on the nds32. -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#ifdef CONFIG_CACHE_L2 -+#include -+#endif -+#include -+ -+#include -+extern struct cache_info L1_cache_info[2]; -+ -+#ifdef CONFIG_CACHE_L2 -+void n12_L2cache_inval(void) -+{ -+ unsigned long cmd = CCTL_CMD_L2_IX_INVAL | CCTL_ALL_CMD; -+ -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, CCTL_CMD_L2_SYNC); -+ L2_CMD_RDY(); -+} -+ -+void n12_L2cache_wb(void) -+{ -+ unsigned long cmd = CCTL_CMD_L2_IX_WB | CCTL_ALL_CMD; -+ -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, CCTL_CMD_L2_SYNC); -+ L2_CMD_RDY(); -+} -+#endif -+ -+int va_kernel_present(unsigned long addr) -+{ -+ pmd_t *pmd; -+ pte_t *ptep, pte; -+ int ret = 0; -+ -+ pmd = pmd_offset(pgd_offset_k(addr), addr); -+ if (!pmd_none(*pmd)) { -+ ptep = pte_offset_map(pmd, addr); -+ pte = *ptep; -+ if (pte_present(pte)) -+ ret = 1; -+ } -+ return ret; -+} -+ -+int va_present(struct mm_struct *mm, unsigned long addr) -+{ -+ pgd_t *pgd; -+ pud_t *pud; -+ pmd_t *pmd; -+ pte_t *ptep, pte; -+ int ret = 0; -+ -+ pgd = pgd_offset(mm, addr); -+ if (!pgd_none(*pgd)) { -+ pud = pud_offset(pgd, addr); -+ if (!pud_none(*pud)) { -+ pmd = pmd_offset(pud, addr); -+ if (!pmd_none(*pmd)) { -+ ptep = pte_offset_map(pmd, addr); -+ pte = *ptep; -+ if (pte_present(pte)) -+ ret = 1; -+ } -+ } -+ } -+ return ret; -+ -+} -+ -+int va_readable(struct pt_regs *regs, unsigned long addr) -+{ -+ struct mm_struct *mm = current->mm; -+ pgd_t *pgd; -+ pud_t *pud; -+ pmd_t *pmd; -+ pte_t *ptep, pte; -+ int ret = 0; -+ -+ if (user_mode(regs)) { -+ /* user mode */ -+ pgd = pgd_offset(mm, addr); -+ if (!pgd_none(*pgd)) { -+ pud = pud_offset(pgd, addr); -+ if (!pud_none(*pud)) { -+ pmd = pmd_offset(pud, addr); -+ if (!pmd_none(*pmd)) { -+ ptep = pte_offset_map(pmd, addr); -+ pte = *ptep; -+ if (pte_present(pte) && pte_read(pte)) -+ ret = 1; -+ } -+ } -+ } -+ } else { -+ /* superuser mode is always readable, so we can only -+ * check it is present or not*/ -+ pmd = pmd_offset(pgd_offset_k(addr), addr); -+ if (!pmd_none(*pmd)) { -+ ptep = pte_offset_map(pmd, addr); -+ pte = *ptep; -+ if (pte_present(pte)) -+ ret = 1; -+ } -+ } -+ return ret; -+} -+ -+int va_writable(struct pt_regs *regs, unsigned long addr) -+{ -+ struct mm_struct *mm = current->mm; -+ pgd_t *pgd; -+ pud_t *pud; -+ pmd_t *pmd; -+ pte_t *ptep, pte; -+ int ret = 0; -+ -+ if (user_mode(regs)) { -+ /* user mode */ -+ pgd = pgd_offset(mm, addr); -+ if (!pgd_none(*pgd)) { -+ pud = pud_offset(pgd, addr); -+ if (!pud_none(*pud)) { -+ pmd = pmd_offset(pud, addr); -+ if (!pmd_none(*pmd)) { -+ ptep = pte_offset_map(pmd, addr); -+ pte = *ptep; -+ if (pte_present(pte) && pte_write(pte)) -+ ret = 1; -+ } -+ } -+ } -+ } else { -+ /* superuser mode */ -+ pmd = pmd_offset(pgd_offset_k(addr), addr); -+ if (!pmd_none(*pmd)) { -+ ptep = pte_offset_map(pmd, addr); -+ pte = *ptep; -+ if (pte_present(pte) && pte_kernel_write(pte)) -+ ret = 1; -+ } -+ } -+ return ret; -+} -+ -+#if 0 -+static inline void flush_fill_buffer(void) -+{ -+ unsigned long kaddr, pte, flags; -+ -+ local_irq_save(flags); -+#define BASE_ADDR2 0xffff4000 -+ kaddr = BASE_ADDR2; -+ pte = (0x6000 | _PAGE_V | _PAGE_M_KRW | _PAGE_G | _PAGE_C_DEV); -+ asm("tlbop %0, INV\nisb\n"::"r"(kaddr)); -+ asm("mtsr %1, $mr2\ndsb\n" -+ "tlbop %0, RWR\nisb\n"::"r"(pte), "r"(kaddr)); -+asm("lmw.bi $r0, [%0], $r1\n"::"r"(kaddr):"$r0", "$r1"); -+ local_irq_restore(flags); -+} -+#else -+static inline void flush_fill_buffer(void) -+{ -+} -+#endif -+ -+/* -+ * All -+ */ -+void n12_icache_inval_all(void) -+{ -+ unsigned long end, line_size; -+ -+ line_size = L1_cache_info[ICACHE].line_size; -+ end = -+ line_size * L1_cache_info[ICACHE].ways * L1_cache_info[ICACHE].sets; -+ -+ do { -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_IX_INVAL"::"r" (end)); -+ } while (end > 0); -+} -+ -+void n12_dcache_inval_all(void) -+{ -+#ifdef CONFIG_PLAT_AG102 -+ __asm__ volatile ("\n\tcctl L1D_INVALALL"); -+#else -+ unsigned long end, line_size; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ end = -+ line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets; -+ -+ do { -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+ } while (end > 0); -+#endif -+} -+ -+void n12_dcache_wb_all(void) -+{ -+#ifdef __NDS32_BASELINE_V3 -+#ifdef CONFIG_CACHE_L2 -+ __nds32__cctl_l1d_wball_alvl(); -+#else -+ __nds32__cctl_l1d_wball_one_lvl(); -+#endif -+#else -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ unsigned long end, line_size; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ end = -+ line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets; -+ -+ do { -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+ } while (end > 0); -+#endif -+#endif -+} -+ -+void n12_dcache_wbinval_all(void) -+{ -+ unsigned long end, line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ unsigned long saved_gie; -+#endif -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ end = -+ line_size * L1_cache_info[DCACHE].ways * L1_cache_info[DCACHE].sets; -+ -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ GIE_SAVE(&saved_gie); -+#endif -+#ifdef __NDS32_BASELINE_V3 -+#ifdef CONFIG_CACHE_L2 -+ __nds32__cctl_l1d_wball_alvl(); -+#else -+ __nds32__cctl_l1d_wball_one_lvl(); -+#endif -+ __nds32__cctl_l1d_invalall(); -+#else -+ do { -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+#endif -+#ifndef CONFIG_PLAT_AG102 -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+#endif -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+#endif -+#ifndef CONFIG_PLAT_AG102 -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+#endif -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+#endif -+#ifndef CONFIG_PLAT_AG102 -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+#endif -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_WB"::"r" (end)); -+#endif -+#ifndef CONFIG_PLAT_AG102 -+ __asm__ volatile ("\n\tcctl %0, L1D_IX_INVAL"::"r" (end)); -+#endif -+ } while (end > 0); -+#ifdef CONFIG_PLAT_AG102 -+ __asm__ volatile ("\n\tcctl L1D_INVALALL"); -+#endif -+#endif -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ GIE_RESTORE(saved_gie); -+#endif -+} -+ -+/* -+ * Page -+ */ -+void n12_icache_inval_page(unsigned long start) -+{ -+ unsigned long line_size, end; -+ -+ line_size = L1_cache_info[ICACHE].line_size; -+ end = start + PAGE_SIZE; -+ -+ do { -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (end)); -+ } while (end != start); -+} -+ -+void n12_dcache_inval_page(unsigned long start) -+{ -+ unsigned long line_size, end; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ end = start + PAGE_SIZE; -+ -+ flush_fill_buffer(); -+ do { -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ } while (end != start); -+} -+ -+void n12_dcache_wb_page(unsigned long start) -+{ -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ unsigned long line_size, end; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ end = start + PAGE_SIZE; -+ -+ flush_fill_buffer(); -+ do { -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+ end -= line_size; -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+ } while (end != start); -+#endif -+} -+ -+void n12_dcache_wbinval_page(unsigned long start) -+{ -+ unsigned long line_size, end; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ end = start + PAGE_SIZE; -+ -+ flush_fill_buffer(); -+ do { -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+#endif -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+#endif -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+#endif -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ end -= line_size; -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (end)); -+#endif -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (end)); -+ } while (end != start); -+} -+ -+void n12_cache_wbinval_page(unsigned long page, int flushi) -+{ -+ n12_dcache_wbinval_page(page); -+ if (flushi) -+ n12_icache_inval_page(page); -+} -+ -+/* These functions are used to invalidate cache by idx instead of -+ * virtual address. User can use virtual address to do this purpose. -+ * It supports 4way and 32KB cache size with 32bytes cacheline size. */ -+#include -+//#define WB_WITH_IDX -+inline unsigned long va2idx(unsigned long va, unsigned int cache_type, -+ unsigned long *way_offset) -+{ -+ unsigned char set_bits, way_bits, line_bits; -+ unsigned int idx; -+ set_bits = L1_cache_info[cache_type].set_bits; -+ way_bits = L1_cache_info[cache_type].way_bits; -+ line_bits = L1_cache_info[cache_type].line_bits; -+ *way_offset = set_bits + line_bits; -+ -+ idx = (va & (((1 << set_bits) - 1) << line_bits)); -+ return idx; -+} -+ -+static inline void n12_dcache_inval_idx(unsigned long p) -+{ -+ unsigned long idx, i, way_offset; -+ unsigned char ways; -+ ways = L1_cache_info[DCACHE].ways; -+ -+ /* Unroll loop. Not support 2 ways invalidate. */ -+ if (ways == 2) -+ panic("This way size is not supported. ways:%u, %s\n", ways, -+ __func__); -+ idx = va2idx(p, DCACHE, &way_offset); -+ for (i = 0; i < ways / 4; i++) { -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | i << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | (i + 1) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | (i + 2) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | (i + 3) << way_offset)); -+ } -+} -+ -+static inline void n12_dcache_wb_idx(unsigned long p) -+{ -+ unsigned long idx, i, way_offset; -+ unsigned char ways; -+ ways = L1_cache_info[DCACHE].ways; -+ -+ /* Unroll the loop. Not support 2 ways invalidate. */ -+ if (ways == 2) -+ panic("This way size is not supported. ways:%d, %s\n", ways, -+ __func__); -+ idx = va2idx(p, DCACHE, &way_offset); -+ for (i = 0; i < ways / 4; i++) { -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | i << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | i << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | (i + 1) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | (i + 1) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | (i + 2) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | (i + 2) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | (i + 3) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_INVAL, -+ (idx | (i + 3) << way_offset)); -+ } -+} -+ -+static inline void n12_dcache_wbinval_idx(unsigned long p) -+{ -+ unsigned long idx, i, way_offset; -+ unsigned char ways; -+ ways = L1_cache_info[DCACHE].ways; -+ -+ /* Unroll the loop. Not support 2 ways invalidate. */ -+ if (ways == 2) -+ panic("This way size is not supported. ways:%d, %s\n", ways, -+ __func__); -+ idx = va2idx(p, DCACHE, &way_offset); -+ for (i = 0; i < ways / 4; i++) { -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | i << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | (i + 1) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | (i + 2) << way_offset)); -+ __nds32__cctlidx_wbinval(NDS32_CCTL_L1D_IX_WB, -+ (idx | (i + 3) << way_offset)); -+ } -+} -+ -+/* -+ * Range -+ */ -+void n12_icache_inval_range(unsigned long start, unsigned long end) -+{ -+ unsigned long line_size; -+ -+ line_size = L1_cache_info[ICACHE].line_size; -+ -+ while (end > start) { -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_INVAL"::"r" (start)); -+ start += line_size; -+ } -+} -+ -+void n12_dcache_inval_range(unsigned long start, unsigned long end) -+{ -+ unsigned long line_size; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ -+ flush_fill_buffer(); -+ while (end > start) { -+#ifdef WB_WITH_IDX -+ n12_dcache_inval_idx(start); -+#else -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start)); -+#endif -+ start += line_size; -+ } -+} -+ -+void n12_dcache_wb_range(unsigned long start, unsigned long end) -+{ -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+ unsigned long line_size; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ -+ flush_fill_buffer(); -+ while (end > start) { -+#ifdef WB_WITH_IDX -+ n12_dcache_wb_idx(start); -+#else -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start)); -+#endif -+ start += line_size; -+ } -+#endif -+} -+ -+void n12_dcache_wbinval_range(unsigned long start, unsigned long end) -+{ -+ unsigned long line_size; -+ -+ line_size = L1_cache_info[DCACHE].line_size; -+ -+ flush_fill_buffer(); -+ while (end > start) { -+#ifndef CONFIG_CPU_DCACHE_WRITETHROUGH -+#ifdef WB_WITH_IDX -+ n12_dcache_wbinval_idx(start); -+#else -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_WB"::"r" (start)); -+#endif -+#endif -+ __asm__ volatile ("\n\tcctl %0, L1D_VA_INVAL"::"r" (start)); -+ start += line_size; -+ } -+} -+ -+void n12_cache_wbinval_range(unsigned long start, unsigned long end, int flushi) -+{ -+ n12_dcache_wbinval_range(start, end); -+ if (flushi) -+ n12_icache_inval_range(start, end); -+} -+ -+void n12_cache_wbinval_range_check(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+ unsigned long line_size, t_start, t_end; -+ int flushi; -+ -+ flushi = vma->vm_flags & VM_EXEC; -+ line_size = L1_cache_info[DCACHE].line_size; -+ start = start & ~(line_size - 1); -+ end = (end + line_size - 1) & ~(line_size - 1); -+ -+ if ((end - start) > (8 * PAGE_SIZE)) { -+ n12_dcache_wbinval_all(); -+ if (flushi) -+ n12_icache_inval_all(); -+ return; -+ } -+ -+ t_start = (start + PAGE_SIZE) & PAGE_MASK; -+ t_end = ((end - 1) & PAGE_MASK); -+ -+ if ((start & PAGE_MASK) == t_end) { -+ if (va_present(vma->vm_mm, start)) -+ n12_cache_wbinval_range(start, end, flushi); -+ return; -+ } -+ -+ if (va_present(vma->vm_mm, start)) -+ n12_cache_wbinval_range(start, t_start, flushi); -+ -+ if (va_present(vma->vm_mm, end - 1)) -+ n12_cache_wbinval_range(t_end, end, flushi); -+ -+ while (t_start < t_end) { -+ if (va_present(vma->vm_mm, t_start)) -+ n12_cache_wbinval_page(t_start, flushi); -+ t_start += PAGE_SIZE; -+ } -+} -+ -+/* -+ * DMA -+ */ -+void n12_dma_wb_range(unsigned long start, unsigned long end) -+{ -+ unsigned long line_size; -+ line_size = L1_cache_info[DCACHE].line_size; -+ start = start & (~(line_size - 1)); -+ end = (end + line_size - 1) & (~(line_size - 1)); -+ if (unlikely(start == end)) -+ return; -+ -+ n12_dcache_wb_range(start, end); -+ -+#ifdef CONFIG_CACHE_L2 -+ { -+ unsigned long p_start = __pa(start); -+ unsigned long p_end = __pa(end); -+ unsigned long cmd; -+ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE -+ line_size = L2_CACHE_LINE_SIZE(); -+ cmd = -+ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WB | -+ CCTL_SINGLE_CMD; -+ do { -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ cmd += line_size; -+ p_start += line_size; -+ } while (p_end > p_start); -+ cmd = CCTL_CMD_L2_SYNC; -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ L2_CMD_RDY(); -+ -+ } -+#endif -+} -+ -+#ifdef CONFIG_CACHE_L2 -+void n12_l2dcache_wbinval_range(unsigned long start, unsigned long end) -+{ -+ unsigned long p_start; -+ unsigned long p_end; -+ unsigned long cmd; -+ unsigned long line_size; -+ -+ p_start = __pa(start); -+ p_end = __pa(end); -+ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE -+ line_size = L2_CACHE_LINE_SIZE(); -+ cmd = -+ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WBINVAL | -+ CCTL_SINGLE_CMD; -+ do { -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ cmd += line_size; -+ p_start += line_size; -+ } while (p_end > p_start); -+ cmd = CCTL_CMD_L2_SYNC; -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ L2_CMD_RDY(); -+ -+} -+#endif -+ -+void n12_dma_inval_range(unsigned long start, unsigned long end) -+{ -+ unsigned long line_size; -+ unsigned long old_start = start; -+ unsigned long old_end = end; -+ line_size = L1_cache_info[DCACHE].line_size; -+ start = start & (~(line_size - 1)); -+ end = (end + line_size - 1) & (~(line_size - 1)); -+ if (unlikely(start == end)) -+ return; -+ if (start != old_start) { -+ n12_dcache_wbinval_range(start, start + line_size); -+#ifdef CONFIG_CACHE_L2 -+ n12_l2dcache_wbinval_range(start, start + line_size); -+#endif -+ } -+ if (end != old_end) { -+ n12_dcache_wbinval_range(end - line_size, end); -+#ifdef CONFIG_CACHE_L2 -+ n12_l2dcache_wbinval_range(end - line_size, end); -+#endif -+ } -+ n12_dcache_inval_range(start, end); -+#ifdef CONFIG_CACHE_L2 -+ unsigned long p_start = __pa(start); -+ unsigned long p_end = __pa(end); -+ unsigned long cmd; -+ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE -+ line_size = L2_CACHE_LINE_SIZE(); -+ cmd = -+ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_INVAL | -+ CCTL_SINGLE_CMD; -+ do { -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ cmd += line_size; -+ p_start += line_size; -+ } while (p_end > p_start); -+ cmd = CCTL_CMD_L2_SYNC; -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ L2_CMD_RDY(); -+#endif -+ -+} -+ -+void n12_dma_wbinval_range(unsigned long start, unsigned long end) -+{ -+ unsigned long line_size; -+ line_size = L1_cache_info[DCACHE].line_size; -+ start = start & (~(line_size - 1)); -+ end = (end + line_size - 1) & (~(line_size - 1)); -+ if (unlikely(start == end)) -+ return; -+ -+ n12_dcache_wbinval_range(start, end); -+#ifdef CONFIG_CACHE_L2 -+ { -+ unsigned long p_start = __pa(start); -+ unsigned long p_end = __pa(end); -+ unsigned long cmd; -+ //TODO Can Use PAGE Mode to optimize if range large than PAGE_SIZE -+ line_size = L2_CACHE_LINE_SIZE(); -+ cmd = -+ (p_start & ~(line_size - 1)) | CCTL_CMD_L2_PA_WBINVAL | -+ CCTL_SINGLE_CMD; -+ do { -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ cmd += line_size; -+ p_start += line_size; -+ } while (p_end > p_start); -+ cmd = CCTL_CMD_L2_SYNC; -+ L2_CMD_RDY(); -+ L2C_W_REG(L2_CCTL_CMD_OFF, cmd); -+ L2_CMD_RDY(); -+ -+ } -+#endif -+} -+ -+void n12_proc_init(void) -+{ -+} -+ -+void n12_proc_fin(void) -+{ -+} -+ -+void n12_do_idle(void) -+{ -+ STANDBY(no_wake_grant); -+} -+ -+void n12_reset(unsigned long reset) -+{ -+ GIE_DISABLE(); -+ SET_CACHE_CTL(GET_CACHE_CTL() & -+ ~(CACHE_CTL_mskIC_EN | CACHE_CTL_mskDC_EN)); -+ n12_dcache_wbinval_all(); -+ n12_icache_inval_all(); -+ -+ __asm__ __volatile__("jr.toff %0\n\t"::"r"(reset)); -+} -+ -+void n12_switch_mm(struct mm_struct *mm) -+{ -+ unsigned long cid; -+#ifndef CONFIG_CPU_NO_CONTEXT_ID -+ cid = GET_TLB_MISC(); -+ cid = (cid & ~TLB_MISC_mskCID) | mm->context.id; -+ SET_TLB_MISC(cid); -+#endif -+ SET_L1_PPTB(__pa(mm->pgd)); -+ //workaround N10 single-entry cache flush issue -+ //the following line can be removed once the issue is fixed. -+ __asm__ __volatile__("tlbop %0, INV"::"r"(cid)); -+ __nds32__isb(); -+#ifdef CONFIG_CPU_NO_CONTEXT_ID -+ local_flush_tlb_mm(mm); -+#endif -+} -diff -Nur linux-3.4.113.orig/arch/nds32/mm/tlb.c linux-3.4.113/arch/nds32/mm/tlb.c ---- linux-3.4.113.orig/arch/nds32/mm/tlb.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/mm/tlb.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,47 @@ -+#include -+#include -+#include -+#include -+#include -+ -+unsigned int cpu_last_cid = { TLB_MISC_mskCID + (2 << TLB_MISC_offCID) }; -+ -+DEFINE_SPINLOCK(cid_lock); -+ -+void local_flush_tlb_range(struct vm_area_struct *vma, -+ unsigned long start, unsigned long end) -+{ -+ unsigned long flags, ocid, ncid; -+ -+ if ((end - start) > 0x400000) { -+ asm("tlbop FLUA"); -+ __nds32__isb(); -+ return; -+ } -+ -+ spin_lock_irqsave(&cid_lock, flags); -+ ocid = GET_TLB_MISC(); -+ ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id; -+ SET_TLB_MISC(ncid); -+ while (start < end) { -+ asm("tlbop %0, INV"::"r"(start)); -+ __nds32__isb(); -+ start += PAGE_SIZE; -+ } -+ SET_TLB_MISC(ocid); -+ spin_unlock_irqrestore(&cid_lock, flags); -+} -+ -+void local_flush_tlb_page(struct vm_area_struct *vma, unsigned long addr) -+{ -+ unsigned long flags, ocid, ncid; -+ -+ spin_lock_irqsave(&cid_lock, flags); -+ ocid = GET_TLB_MISC(); -+ ncid = (ocid & ~TLB_MISC_mskCID) | vma->vm_mm->context.id; -+ SET_TLB_MISC(ncid); -+ asm("tlbop %0, INV"::"r"(addr)); -+ __nds32__isb(); -+ SET_TLB_MISC(ocid); -+ spin_unlock_irqrestore(&cid_lock, flags); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/oprofile/common.c linux-3.4.113/arch/nds32/oprofile/common.c ---- linux-3.4.113.orig/arch/nds32/oprofile/common.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/oprofile/common.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,104 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2004, 2005 Ralf Baechle -+ * Copyright (C) 2005 MIPS Technologies, Inc. -+ * Copyright (C) 2008 Andes Technology Corporation -+ */ -+#include -+#include -+#include -+#include -+ -+#include "op_impl.h" -+ -+extern struct op_nds32_model op_model_nds32_ops __attribute__ ((weak)); -+ -+static struct op_nds32_model *model; -+ -+static struct op_counter_config ctr[20]; -+ -+static int op_nds32_setup(void) -+{ -+ /* Pre-compute the values to stuff in the hardware registers. */ -+ model->reg_setup(ctr); -+ -+ /* Configure the registers on all cpus. */ -+ on_each_cpu(model->cpu_setup, NULL, 1); -+ -+ return 0; -+} -+ -+static int op_nds32_create_files(struct super_block *sb, struct dentry *root) -+{ -+ int i; -+ -+ for (i = 0; i < model->num_counters; ++i) { -+ struct dentry *dir; -+ char buf[4]; -+ -+ snprintf(buf, sizeof buf, "%d", i); -+ dir = oprofilefs_mkdir(sb, root, buf); -+ -+ oprofilefs_create_ulong(sb, dir, "enabled", &ctr[i].enabled); -+ oprofilefs_create_ulong(sb, dir, "event", &ctr[i].event); -+ oprofilefs_create_ulong(sb, dir, "count", &ctr[i].count); -+ oprofilefs_create_ulong(sb, dir, "kernel", &ctr[i].kernel); -+ oprofilefs_create_ulong(sb, dir, "user", &ctr[i].user); -+ oprofilefs_create_ulong(sb, dir, "exl", &ctr[i].exl); -+ /* Dummy. */ -+ oprofilefs_create_ulong(sb, dir, "unit_mask", -+ &ctr[i].unit_mask); -+ } -+ -+ return 0; -+} -+ -+static int op_nds32_start(void) -+{ -+ on_each_cpu(model->cpu_start, NULL, 1); -+ -+ return 0; -+} -+ -+static void op_nds32_stop(void) -+{ -+ /* Disable performance monitoring for all counters. */ -+ on_each_cpu(model->cpu_stop, NULL, 1); -+} -+ -+int __init oprofile_arch_init(struct oprofile_operations *ops) -+{ -+ struct op_nds32_model *lmodel = NULL; -+ int res; -+ -+ lmodel = &op_model_nds32_ops; -+ -+ if (!lmodel) -+ return -ENODEV; -+ -+ res = lmodel->init(); -+ if (res) -+ return res; -+ -+ model = lmodel; -+ -+ ops->create_files = op_nds32_create_files; -+ ops->setup = op_nds32_setup; -+ ops->start = op_nds32_start; -+ ops->stop = op_nds32_stop; -+ ops->cpu_type = lmodel->cpu_type; -+ -+ printk(KERN_INFO "oprofile: using %s performance monitoring.\n", -+ lmodel->cpu_type); -+ -+ return 0; -+} -+ -+void oprofile_arch_exit(void) -+{ -+ if (model) -+ model->exit(); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/oprofile/Makefile linux-3.4.113/arch/nds32/oprofile/Makefile ---- linux-3.4.113.orig/arch/nds32/oprofile/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/oprofile/Makefile 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,11 @@ -+EXTRA_CFLAGS := -+ -+obj-$(CONFIG_OPROFILE) += oprofile.o -+ -+DRIVER_OBJS = $(addprefix ../../../drivers/oprofile/, \ -+ oprof.o cpu_buffer.o buffer_sync.o \ -+ event_buffer.o oprofile_files.o \ -+ oprofilefs.o oprofile_stats.o \ -+ timer_int.o ) -+ -+oprofile-y := $(DRIVER_OBJS) common.o op_model_nds32.o -diff -Nur linux-3.4.113.orig/arch/nds32/oprofile/op_impl.h linux-3.4.113/arch/nds32/oprofile/op_impl.h ---- linux-3.4.113.orig/arch/nds32/oprofile/op_impl.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/oprofile/op_impl.h 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,42 @@ -+/** -+ * @file arch/alpha/oprofile/op_impl.h -+ * -+ * @remark Copyright 2002 OProfile authors -+ * @remark Read the file COPYING -+ * -+ * @author Richard Henderson -+ */ -+ -+#ifndef OP_IMPL_H -+#define OP_IMPL_H 1 -+ -+struct pt_regs; -+ -+extern int null_perf_irq(struct pt_regs *regs); -+extern int (*perf_irq)(struct pt_regs *regs); -+ -+/* Per-counter configuration as set via oprofilefs. */ -+struct op_counter_config { -+ unsigned long enabled; -+ unsigned long event; -+ unsigned long count; -+ /* Dummies because I am too lazy to hack the userspace tools. */ -+ unsigned long kernel; -+ unsigned long user; -+ unsigned long exl; -+ unsigned long unit_mask; -+}; -+ -+/* Per-architecture configury and hooks. */ -+struct op_nds32_model { -+ void (*reg_setup) (struct op_counter_config *); -+ void (*cpu_setup) (void * dummy); -+ int (*init)(void); -+ void (*exit)(void); -+ void (*cpu_start)(void *args); -+ void (*cpu_stop)(void *args); -+ char *cpu_type; -+ unsigned char num_counters; -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/oprofile/op_model_nds32.c linux-3.4.113/arch/nds32/oprofile/op_model_nds32.c ---- linux-3.4.113.orig/arch/nds32/oprofile/op_model_nds32.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/oprofile/op_model_nds32.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,400 @@ -+/* -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ * -+ * Copyright (C) 2004, 2005 by Ralf Baechle -+ * Copyright (C) 2005 by MIPS Technologies, Inc. -+ * Copyright (C) 2007 Andes Technology Corporation -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "op_impl.h" -+ -+#ifdef CONFIG_PLAT_AG102 -+#include -+#define NDS32_PERFCNTR_IRQA 23 -+#define NDS32_PERFCNTR_IRQB 22 -+#else -+#define NDS32_PERFCNTR_IRQA 10 -+#endif -+#define NDS32_PERFCTL_EN(num) (1 << num) -+#define NDS32_PERFCTL_INTEN (1UL << 3) -+#define NDS32_PERFCTL_OVERFLOW (1UL << 6) -+#define NDS32_PERFCTL_NOKERNEL (1UL << 9) -+#define NDS32_PERFCTL_NOUSER (1UL << 12) -+#define NDS32_PERFCTL_EVENT_0(event) (event << 15) -+#define NDS32_PERFCTL_EVENT_1(event) (event << 16) -+#define NDS32_PERFCTL_EVENT_2(event) (event << 22) -+ -+static unsigned long long ov0, ov1, ov2; -+static int syscall = 0; -+ -+struct pmu_counter { -+ volatile unsigned long ovf; -+ unsigned long reset_counter; -+}; -+ -+enum { PFMC0, PFMC1, PFMC2, MAX_COUNTERS }; -+ -+static struct pmu_counter results[MAX_COUNTERS]; -+ -+static inline unsigned int read_perfcntr(int counter) -+{ -+ switch (counter) { -+ case PFMC0: -+ return GET_PFMC0(); -+ break; -+ case PFMC1: -+ return GET_PFMC1(); -+ break; -+ case PFMC2: -+ return GET_PFMC2(); -+ break; -+ default: -+ printk(KERN_ERR -+ "Oprofile read_perfcntr: CPU has no %d performance counters\n", -+ counter); -+ } -+ -+ return 0; -+} -+ -+static inline unsigned int read_perfctrl(void) -+{ -+ return GET_PFM_CTL(); -+} -+ -+static inline void write_perfcntr(int counter, unsigned int value) -+{ -+ switch (counter) { -+ case PFMC0: -+ SET_PFMC0(value); -+ break; -+ case PFMC1: -+ SET_PFMC1(value); -+ break; -+ case PFMC2: -+ SET_PFMC2(value); -+ break; -+ default: -+ printk(KERN_ERR -+ "Oprofile write_perfcntr: CPU has no %d performance counters\n", -+ counter); -+ } -+} -+ -+static inline void write_perfctrl(unsigned int value) -+{ -+ SET_PFM_CTL(value); -+} -+ -+struct op_nds32_model op_model_nds32_ops; -+ -+static struct nds32_register_config { -+ unsigned int control[3]; -+ unsigned int counter[3]; -+} reg; -+ -+/* Compute all of the registers in preparation for enabling profiling. */ -+ -+static void nds32_reg_setup(struct op_counter_config *ctr) -+{ -+ unsigned int counters = op_model_nds32_ops.num_counters; -+ int i; -+ -+ /* Compute the performance counter control word. */ -+ /* For now count kernel and user mode */ -+ for (i = 0; i < counters; i++) { -+ reg.control[i] = 0; -+ reg.counter[i] = 0; -+ -+ if (!ctr[i].enabled) -+ continue; -+ -+ switch (i) { -+ case 0: -+ reg.control[i] = NDS32_PERFCTL_EVENT_0(ctr[i].event) | -+ (NDS32_PERFCTL_INTEN << i); -+ break; -+ case 1: -+ reg.control[i] = NDS32_PERFCTL_EVENT_1(ctr[i].event) | -+ (NDS32_PERFCTL_INTEN << i); -+ break; -+ case 2: -+ reg.control[i] = NDS32_PERFCTL_EVENT_2(ctr[i].event) | -+ (NDS32_PERFCTL_INTEN << i); -+ break; -+ default: -+ printk(KERN_ERR -+ "Oprofile nds32_reg_setup: CPU has no %d performance counters\n", -+ i); -+ } -+ if (!(ctr[i].kernel)) -+ reg.control[i] |= (NDS32_PERFCTL_NOKERNEL << i); -+ if (!(ctr[i].user)) -+ reg.control[i] |= (NDS32_PERFCTL_NOUSER << i); -+ reg.counter[i] = -ctr[i].count; -+ } -+} -+ -+/* Program all of the registers in preparation for enabling profiling. */ -+ -+static void nds32_cpu_setup(void *args) -+{ -+ unsigned int counters = op_model_nds32_ops.num_counters; -+ -+ switch (counters) { -+ case 3: -+ write_perfcntr(2, reg.counter[2]); -+ case 2: -+ write_perfcntr(1, reg.counter[1]); -+ case 1: -+ write_perfcntr(0, reg.counter[0]); -+ } -+ write_perfctrl(0); -+} -+ -+/* Start all counters on current CPU */ -+static void nds32_cpu_start(void *args) -+{ -+ unsigned int counters = op_model_nds32_ops.num_counters; -+ unsigned int value = 0; -+ -+ switch (counters) { -+ case 3: -+ if (reg.control[2]) -+ value |= (NDS32_PERFCTL_EN(2) | reg.control[2]); -+ case 2: -+ if (reg.control[1]) -+ value |= (NDS32_PERFCTL_EN(1) | reg.control[1]); -+ case 1: -+ if (reg.control[0]) -+ value |= (NDS32_PERFCTL_EN(0) | reg.control[0]); -+ } -+ write_perfctrl(value); -+} -+ -+/* Stop all counters on current CPU */ -+static void nds32_cpu_stop(void *args) -+{ -+ write_perfctrl(0); -+} -+ -+static irqreturn_t nds32_perfcount_handler(int irq, void *dev_id) -+{ -+ unsigned int control, i; -+ -+ control = read_perfctrl(); -+ write_perfctrl(0); -+ -+ if (syscall) { -+ if (control & PFM_CTL_mskOVF0) -+ ov0++; -+ if (control & PFM_CTL_mskOVF1) -+ ov1++; -+ if (control & PFM_CTL_mskOVF2) -+ ov2++; -+ } else { -+ for (i = 0; i < MAX_COUNTERS; i++) { -+ if ((control & (NDS32_PERFCTL_INTEN << i)) -+ && (control & (NDS32_PERFCTL_OVERFLOW << i))) { -+ oprofile_add_sample(get_irq_regs(), i); -+ write_perfcntr(i, reg.counter[i]); -+ break; -+ } -+ } -+ } -+ write_perfctrl(control); -+ -+ return IRQ_HANDLED; -+} -+ -+static inline int n_counters(void) -+{ -+ return 3; -+} -+ -+static inline void reset_counters(int counters) -+{ -+ switch (counters) { -+ case 3: -+ write_perfcntr(2, 0); -+ case 2: -+ write_perfcntr(1, 0); -+ case 1: -+ write_perfcntr(0, 0); -+ } -+ write_perfctrl(0); -+} -+ -+static int __init nds32_init(void) -+{ -+ int counters, ret; -+ -+ counters = n_counters(); -+ if (counters == 0) { -+ printk(KERN_ERR "Oprofile: CPU has no performance counters\n"); -+ return -ENODEV; -+ } -+ -+ reset_counters(counters); -+ -+ op_model_nds32_ops.num_counters = counters; -+ op_model_nds32_ops.cpu_type = "nds32"; -+ -+ ret = -+ request_irq(NDS32_PERFCNTR_IRQA, nds32_perfcount_handler, -+ IRQF_SHARED, "NDS32 PERFCNTR", (void *)results); -+ if (ret < 0) { -+ printk(KERN_ERR "oprofile: unable to request IRQ%d\n", -+ NDS32_PERFCNTR_IRQA); -+ return ret; -+ } -+#ifdef CONFIG_PLAT_AG102 -+ unsigned int tmp; -+ /* Set NDS32_PERFCNTR_IRQA to bind on core A */ -+ tmp = -+ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + -+ ((NDS32_PERFCNTR_IRQA >> 4) << 2)); -+ tmp &= ~(0x11 << ((NDS32_PERFCNTR_IRQA & ~0x10) * 2)); -+ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + -+ ((NDS32_PERFCNTR_IRQA >> 4) << 2)) = tmp; -+ tmp = -+ (*(volatile unsigned long *)(AMIC_VA_BASE + CPUDC)) & ~(1 << -+ NDS32_PERFCNTR_IRQA); -+ *(volatile unsigned long *)(AMIC_VA_BASE + CPUDC) = tmp; -+ -+ ret = -+ request_irq(NDS32_PERFCNTR_IRQB, nds32_perfcount_handler, -+ IRQF_SHARED, "NDS32 PERFCNTR", (void *)results); -+ if (ret < 0) { -+ printk(KERN_ERR "oprofile: unable to request IRQ%d\n", -+ NDS32_PERFCNTR_IRQB); -+ return ret; -+ } -+ /* Set NDS32_PERFCNTR_IRQB to bind on core B */ -+ tmp = -+ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + -+ ((NDS32_PERFCNTR_IRQB >> 4) << 2)); -+ tmp &= ~(0x11 << ((NDS32_PERFCNTR_IRQB & ~0x10) * 2)); -+ tmp |= 1 << ((NDS32_PERFCNTR_IRQB & ~0x10) * 2); -+ *(volatile unsigned long *)(AMIC_VA_BASE + CPUID0 + -+ ((NDS32_PERFCNTR_IRQB >> 4) << 2)) = tmp; -+ tmp = -+ (*(volatile unsigned long *)(AMIC_VA_BASE + CPUDC)) & ~(1 << -+ NDS32_PERFCNTR_IRQB); -+ *(volatile unsigned long *)(AMIC_VA_BASE + CPUDC) = tmp; -+#endif -+ -+ return 0; -+} -+ -+static void nds32_exit(void) -+{ -+ reset_counters(op_model_nds32_ops.num_counters); -+ -+ free_irq(NDS32_PERFCNTR_IRQA, results); -+#ifdef CONFIG_PLAT_AG102 -+ free_irq(NDS32_PERFCNTR_IRQB, results); -+#endif -+} -+ -+void sys_pfmctl(int event0, int event1, int event2, int start) -+{ -+ unsigned int ctl = 0; -+ -+ if (start) { -+ syscall = 1; -+ if (event0 >= 0) -+ ctl |= -+ (NDS32_PERFCTL_EVENT_0(event0) | -+ (NDS32_PERFCTL_INTEN << 0) | NDS32_PERFCTL_EN(0)); -+ if (event1 >= 0) -+ ctl |= -+ (NDS32_PERFCTL_EVENT_1(event1) | -+ (NDS32_PERFCTL_INTEN << 1) | NDS32_PERFCTL_EN(1)); -+ if (event2 >= 0) -+ ctl |= -+ (NDS32_PERFCTL_EVENT_2(event2) | -+ (NDS32_PERFCTL_INTEN << 2) | NDS32_PERFCTL_EN(2)); -+ } else { -+ syscall = 0; -+ if (event0 >= 0) -+ ctl &= -+ ~((NDS32_PERFCTL_INTEN << 0) | NDS32_PERFCTL_EN(0)); -+ if (event1 >= 0) -+ ctl &= -+ ~((NDS32_PERFCTL_INTEN << 1) | NDS32_PERFCTL_EN(1)); -+ if (event2 >= 0) -+ ctl &= -+ ~((NDS32_PERFCTL_INTEN << 2) | NDS32_PERFCTL_EN(2)); -+ } -+ -+ write_perfctrl(ctl); -+ -+} -+ -+int sys_getpfm(struct pcounter __user * p) -+{ -+ struct pcounter pfm; -+ unsigned int control; -+ -+ control = read_perfctrl(); -+ write_perfctrl(0); -+ -+ pfm.pfm0 = ov0 << 32 | GET_PFMC0(); -+ pfm.pfm1 = ov1 << 32 | GET_PFMC1(); -+ pfm.pfm2 = ov2 << 32 | GET_PFMC2(); -+ -+ if (copy_to_user(p, &pfm, sizeof(pfm))) -+ return -EFAULT; -+ -+ write_perfctrl(control); -+ -+ return 0; -+} -+ -+int sys_setpfm(int pfm0, int pfm1, int pfm2, struct pcounter __user * p) -+{ -+ struct pcounter pfm; -+ unsigned int control; -+ -+ control = read_perfctrl(); -+ write_perfctrl(0); -+ -+ if (copy_from_user(&pfm, p, sizeof(pfm))) -+ return -EFAULT; -+ -+ if (pfm0) { -+ SET_PFMC0((unsigned int)(pfm.pfm0 & 0xffffffff)); -+ ov0 = pfm.pfm0 >> 32; -+ } -+ if (pfm1) { -+ SET_PFMC1((unsigned int)(pfm.pfm1 & 0xffffffff)); -+ ov1 = pfm.pfm1 >> 32; -+ } -+ if (pfm2) { -+ SET_PFMC2((unsigned int)(pfm.pfm2 & 0xffffffff)); -+ ov2 = pfm.pfm2 >> 32; -+ } -+ -+ write_perfctrl(control); -+ -+ return 0; -+} -+ -+struct op_nds32_model op_model_nds32_ops = { -+ .reg_setup = nds32_reg_setup, -+ .cpu_setup = nds32_cpu_setup, -+ .init = nds32_init, -+ .exit = nds32_exit, -+ .cpu_start = nds32_cpu_start, -+ .cpu_stop = nds32_cpu_stop, -+}; -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/cpu-fcs.c linux-3.4.113/arch/nds32/platforms/ag101/cpu-fcs.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/cpu-fcs.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/cpu-fcs.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,401 @@ -+/* -+ * linux/arch/nds32/platforms/ag101/cpu-fcs.c -+ * -+ * Copyright (C) 2002,2003 Intrinsyc Software -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * History: -+ * 31-Jul-2002 : Initial version [FB] -+ * 29-Jan-2003 : added PXA255 support [FB] -+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) -+ * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.) -+ * -+ * Note: -+ * This driver may change the memory bus clock rate, but will not do any -+ * platform specific access timing changes... for example if you have flash -+ * memory connected to CS0, you will need to register a platform specific -+ * notifier which will adjust the memory access strobes to maintain a -+ * minimum strobe width. -+ * -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define NDS32_FCS_IRQ 8 -+#define AG101_MIN_FREQ 100000 -+#define AG101_MAX_FREQ 400000 -+#define OSC_KHZ 10000 /* 10 MHz AG101 */ -+ -+#define USE_CACHE 0 -+struct ag101_freq_struct { -+ -+ unsigned int khz; /* cpu_clk in khz */ -+ unsigned int pll; /* pll mul */ -+ unsigned int div; /* ahb div */ -+ unsigned int frange; /* pll1 freq range */ -+}; -+ -+struct ag101_freq_struct ag101_run_freqs[] = { -+ -+ /* khz , pll, div, frange pll/cpu/ahb/apb */ -+ {100000, 10, 2, 0}, /* 400/400/050/025 */ -+ {200000, 20, 4, 1}, /* 400/400/050/025 */ -+ {300000, 30, 6, 2}, /* 400/400/050/025 */ -+ {400000, 40, 8, 2}, /* 400/400/050/025 */ -+ {500000, 50, 10, 3}, /* 500/500/050/025 */ -+ {0,} -+}; -+ -+#define NUM_RUN_FREQS ARRAY_SIZE( ag101_run_freqs) -+static struct cpufreq_frequency_table ag101_run_freq_table[NUM_RUN_FREQS + 1]; -+ -+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ -+static struct ag101_freq_struct ag101_turbo_freqs[] = { -+ -+ /* khz , pll, div, frange pll/cpu/ahb/apb */ -+ {100000, 10, 2, 0}, /* 400/400/050/025 */ -+ {200000, 20, 4, 1}, /* 400/400/050/025 */ -+ {300000, 30, 6, 2}, /* 400/400/050/025 */ -+ {400000, 40, 8, 2}, /* 400/400/050/025 */ -+ {500000, 50, 10, 3}, /* 500/500/050/025 */ -+ {0,} -+}; -+ -+#define NUM_TURBO_FREQS ARRAY_SIZE( ag101_turbo_freqs) -+static struct cpufreq_frequency_table ag101_turbo_freq_table[NUM_TURBO_FREQS + -+ 1]; -+ -+/* Generic helper function get CPU clocks in kHz */ -+unsigned int ag101_cpufreq_get(unsigned int dummy) -+{ -+ -+ unsigned int mul = (REG32(PMU_FTPMU010_VA_BASE + 0x30) >> 3UL) & 0x01ff; /* pll1 mul */ -+ return OSC_KHZ * mul; -+} -+ -+/* find a valid frequency point */ -+static int ag101_verify_policy(struct cpufreq_policy *policy) -+{ -+ -+ struct cpufreq_frequency_table *ag101_freqs_table; -+ -+ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ -+ ag101_freqs_table = ag101_run_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ -+ ag101_freqs_table = ag101_turbo_freq_table; -+ } else { -+ printk -+ ("CPU PXA: Unknown policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ ag101_freqs_table = ag101_run_freq_table; -+ } -+ -+ printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min, -+ policy->max); -+ -+ return cpufreq_frequency_table_verify(policy, ag101_freqs_table); -+} -+ -+static int cal_edivahbclk(int div) -+{ -+ -+ switch (div) { -+ -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ case 6: -+ return --div; -+ case 8: -+ return 8; -+ case 10: -+ return 9; -+ case 12: -+ return 10; -+ case 14: -+ return 11; -+ case 15: -+ return 12; -+ case 18: -+ return 13; -+ case 20: -+ return 14; -+ default: -+ printk("Error: No such CPU/AHB frequency ratio %d", div); -+ } -+ -+ return 9; -+} -+ -+void start_fcs(unsigned int pll, unsigned int frange, unsigned int div) -+{ -+ -+ /* PDLLCR0 */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x30) &= ~0x00003ff8; /* clear PLL1NS and PLL1FRANG fields */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (pll << 3); /* set PLL1NS */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (frange << 12); /* set PLL1FRANG */ -+ -+ /* PMODE */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~0x000000ff; /* clear EDIVAHBCLK field */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (div << 4); /* set EDIVAHBCLK [7:4] */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (1UL << 2); /* [2]: FCS */ -+ -+ __asm__ __volatile__("msync all"); -+ __asm__ __volatile__("isb"); -+ __asm__ __volatile__("standby wake_grant"); -+ REG32(PMU_FTPMU010_VA_BASE + 0x30) |= (1UL << 16); /* PDLLCR0 bit[16]==1:disable dll */ -+} -+ -+void end_fcs(void) -+{ -+ -+ /* Leave this function as a place marker. */ -+} -+ -+static int nds32_fcs_handler(int irq, void *dev_id) -+{ -+ -+ REG32(PMU_FTPMU010_VA_BASE + 0x20) = (1UL << 17); /* Clear IntFCS PMSR[17] */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(1UL << 2); /* Power Mode Register */ -+ -+ return 1; -+} -+ -+static int ag101_speedstep(int idx) -+{ -+ -+ unsigned int pll, frange, div; -+ unsigned long flags = 0; -+ int irq, saved_irq_mask; -+ void (*do_fcs) (unsigned int pll, unsigned int frange, -+ unsigned int div); -+ -+#if USE_CACHE -+ -+ int i; -+ int line_size = CACHE_LINE_SIZE(ICACHE); -+ unsigned long start = ((unsigned long)start_fcs) & ~(line_size - 1); -+ unsigned long end = -+ (((unsigned long)end_fcs) + line_size) & ~(line_size - 1); -+ -+ printk("&start_fcs(): 0x%08lx, aligned to: 0x%08lx\n", -+ (unsigned long)start_fcs, start); -+ printk("&end_fcs(): 0x%08lx, aligned to: 0x%08lx\n", -+ (unsigned long)end_fcs, end); -+ -+ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK":: -+ "r" (i):"memory"); -+ -+ do_fcs = start_fcs; -+#else -+ unsigned long buf, aligned_buf, len = PAGE_SIZE; -+ -+ buf = (unsigned long)kmalloc(0x100000 + 1000, GFP_KERNEL); -+ if (!buf) -+ printk("Error: kmalloc( base) failed\n"); -+ -+ aligned_buf = (buf + 0x100000 - 1) & 0xFFF00000; -+ -+ if (sys_lmmap(LM_ILM, aligned_buf, aligned_buf + 0x1000, 0, NULL)) { -+ printk("Error: lmmap failed, can't scale frequency.\n"); -+#ifdef CONFIG_CPU_FREQ_DEBUG -+ WARN_ON(1); -+#endif -+ return 0; -+ } -+ -+ if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 9) -+ len = 0x400; -+ else if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 10) -+ len = 0x800; -+ memcpy((unsigned char *)aligned_buf, (unsigned char *)start_fcs, len); -+ -+ do_fcs = (void *)aligned_buf; -+#endif -+ pll = ag101_run_freqs[idx].pll; -+ div = cal_edivahbclk(ag101_run_freqs[idx].div); -+ frange = ag101_run_freqs[idx].frange; -+ -+ irq = -+ request_irq(NDS32_FCS_IRQ, nds32_fcs_handler, -+ IRQF_DISABLED | IRQF_TRIGGER_FALLING, -+ "NDS32 Frequency Change Sequence", -+ (void *)ag101_run_freqs); -+ if (irq < 0) -+ printk(KERN_ERR "Error: unable to request FCS IRQ%d\n", -+ NDS32_FCS_IRQ); -+ -+ local_irq_save(flags); -+ -+ saved_irq_mask = REG32(INTC_FTINTC010_VA_BASE + 0x04); -+ REG32(INTC_FTINTC010_VA_BASE + 0x04) = (1UL << NDS32_FCS_IRQ); -+ -+ do_fcs(pll, frange, div); -+ -+ REG32(INTC_FTINTC010_VA_BASE + 0x04) = saved_irq_mask; -+ -+ local_irq_restore(flags); -+ free_irq(NDS32_FCS_IRQ, ag101_run_freqs); -+ -+#if USE_CACHE -+ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory"); -+#else -+ if (sys_lmunmap(aligned_buf, 0)) -+ printk("Error: lmunmap failed\n"); -+ -+ kfree((void *)buf); -+#endif -+ return 1; -+} -+ -+static int ag101_set_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, unsigned int relation) -+{ -+ -+ unsigned int idx; -+ struct cpufreq_frequency_table *ag101_freqs_table; -+ struct ag101_freq_struct *ag101_freq_settings; -+ struct cpufreq_freqs freqs; -+ -+ /* Get the current policy */ -+ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ -+ ag101_freq_settings = ag101_run_freqs; -+ ag101_freqs_table = ag101_run_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ -+ ag101_freq_settings = ag101_turbo_freqs; -+ ag101_freqs_table = ag101_turbo_freq_table; -+ } else { -+ printk -+ ("Unknown FCS policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ ag101_freq_settings = ag101_run_freqs; -+ ag101_freqs_table = ag101_run_freq_table; -+ } -+ -+ /* Lookup the next frequency */ -+ if (cpufreq_frequency_table_target -+ (policy, ag101_freqs_table, target_freq, relation, &idx)) -+ return -EINVAL; -+ -+ freqs.old = policy->cur; -+ freqs.new = ag101_freq_settings[idx].khz; -+ freqs.cpu = policy->cpu; -+ -+ /* -+ * Tell everyone what we're about to do... -+ * you should add a notify client with any platform specific -+ * Vcc changing capability -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+ if (freqs.new != freqs.old) { -+ if (!ag101_speedstep(idx)) -+ return -ENODEV; -+ } -+ -+ /* -+ * Tell everyone what we've just done... -+ * you should add a notify client with any platform specific -+ * SDRAM refresh timer adjustments -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ -+ return 0; -+} -+ -+static int ag101_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ -+ int i; -+ /* set default policy and cpuinfo */ -+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; -+ policy->policy = CPUFREQ_POLICY_PERFORMANCE; -+ policy->cpuinfo.max_freq = AG101_MAX_FREQ; -+ policy->cpuinfo.min_freq = AG101_MIN_FREQ; -+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ -+ policy->cur = ag101_cpufreq_get(0); /* current freq */ -+ policy->min = policy->max = policy->cur; -+ -+ /* Generate the run cpufreq_frequency_table struct */ -+ for (i = 0; i < NUM_RUN_FREQS; i++) { -+ -+ ag101_run_freq_table[i].frequency = ag101_run_freqs[i].khz; -+ ag101_run_freq_table[i].index = i; -+ } -+ -+ ag101_run_freq_table[i].frequency = CPUFREQ_TABLE_END; -+ -+ /* Generate the turbo cpufreq_frequency_table struct */ -+ for (i = 0; i < NUM_TURBO_FREQS; i++) { -+ -+ ag101_turbo_freq_table[i].frequency = ag101_turbo_freqs[i].khz; -+ ag101_turbo_freq_table[i].index = i; -+ } -+ -+ ag101_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; -+ -+ printk("CPU frequency change support initialized\n"); -+ -+ return 0; -+} -+ -+static struct cpufreq_driver ag101_cpufreq_driver = { -+ -+ .verify = ag101_verify_policy, -+ .target = ag101_set_target, -+ .init = ag101_cpufreq_init, -+ .get = ag101_cpufreq_get, -+ .name = "AG101", -+}; -+ -+static int __init ag101_cpu_init(void) -+{ -+ -+ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) { -+ -+ /* Clear IntFS, IntFCS and irq8 */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x20) = (1UL << 16); -+ return cpufreq_register_driver(&ag101_cpufreq_driver); -+ } else -+ return -ENODEV; -+} -+ -+static void __exit ag101_cpu_exit(void) -+{ -+ -+ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) -+ cpufreq_unregister_driver(&ag101_cpufreq_driver); -+} -+ -+MODULE_AUTHOR("Andes Technology Corporation"); -+MODULE_DESCRIPTION("CPU frequency changing driver for the AG101 architecture"); -+MODULE_LICENSE("GPL"); -+module_init(ag101_cpu_init); -+module_exit(ag101_cpu_exit); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/devices.c linux-3.4.113/arch/nds32/platforms/ag101/devices.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/devices.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,94 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+const struct map_desc platform_io_desc[] __initdata = { -+ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, -+ PAGE_SIZE, MT_DEVICE_NCB}, -+ {KMI_FTKBC010_0_VA_BASE, KMI_FTKBC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCNB}, -+ {KMI_FTKBC010_1_VA_BASE, KMI_FTKBC010_1_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCNB}, -+ {USB_FUSB220_0_VA_BASE, USB_FUSB220_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCNB}, -+ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x000FF000, MT_DEVICE_NCB}, -+ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} -+}; -+ -+static void __init platform_map_io(void) -+{ -+ iotable_init((struct map_desc *)platform_io_desc, -+ ARRAY_SIZE(platform_io_desc)); -+} -+ -+static struct uart_port uart0 = { -+ .membase = (void __iomem *)UART0_VA_BASE, -+ .irq = UART0_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 0, -+ .mapbase = UART0_PA_BASE, -+}; -+ -+static struct uart_port uart1 = { -+ .membase = (void __iomem *)UART1_VA_BASE, -+ .irq = UART1_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 1, -+ .mapbase = UART1_PA_BASE, -+}; -+ -+void ag101_calc_ahb_clk(void); -+static void __init soc_init(void) -+{ -+ ag101_calc_ahb_clk(); -+ early_serial_setup(&uart0); -+ early_serial_setup(&uart1); -+} -+ -+MACHINE_START(FARADAY, PLATFORM_NAME) -+ .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = platform_init_irq,.timer = &platform_timer, /* defined in timer.c */ -+ .init_machine = soc_init, MACHINE_END -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/fia320.c linux-3.4.113/arch/nds32/platforms/ag101/fia320.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/fia320.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/fia320.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,103 @@ -+/* -+ * linux/arch/nds32/platforms/ag101/fia320.c -+ * -+ * Faraday A320D Platform Dependent Functions -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/26/2005 Created -+ * Peter Liao 09/29/2005 Port dynamically getting AHB clock -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#ifdef CONFIG_AUTO_SYS_CLK -+#include -+#define AG101B0 (0x0c020003) -+ -+/* -+ * Table for ahb divisor, PMODE[07:04] -+ */ -+static const int ahb_div[16] = { -+ 1, 2, 3, 4, 5, 6, 3, 5, -+ 8, 10, 12, 14, 15, 18, 20, -1 -+}; -+ -+/* ag101_get_ahb_clk() -+ * -+ * return AHB clock in Hz. -+ */ -+static int ahbclk; -+void ag101_calc_ahb_clk(void) -+{ -+ /* -+ * FIXME: We should not put AG101 term in here, Harry@Oct.23.2007 -+ */ -+ const unsigned int osc = 10; // OSC in MHz -+ unsigned int mul, div, cpu, pll; -+ unsigned int ahb = 0; // ahb clk in Hz -+ unsigned int cpu_ver; -+ -+ mul = (REG32(PMU_FTPMU010_0_VA_BASE + 0x30) >> 3) & 0x01ff; // pll1 mul -+ div = (REG32(PMU_FTPMU010_0_VA_BASE + 0x4) >> 8) & 0x000f; // pll1 div -+ ahb = (REG32(PMU_FTPMU010_0_VA_BASE + 0x4) >> 4) & 0x000f; // ahb div -+ div += 1; -+ -+ pll = (osc * mul / div); // depend on OSC. -+ -+ //AG101B0 PLL divider fix -+ cpu_ver = __nds32__mfsr(NDS32_SR_CPU_VER); -+ if (AG101B0 == cpu_ver) -+ pll >>= 1; -+ -+ if (-1 != ahb_div[ahb]) { -+ if ((ahb == 6) || (ahb == 7)) // special cases for 3:2 & 5:2 -+ cpu = pll >> 1; // divide by 2 -+ else -+ cpu = pll; -+ -+ ahb = pll / ahb_div[ahb]; // become ahb clk in MHz. -+ -+ printk("AG101 auto-detected AHB clock: CPU/AHB=%uMHz/%uMHz\n", -+ cpu, ahb); -+ ahb *= 1000000; // become ahb clk in Hz. -+ ahbclk = (int)ahb; -+ } else { -+ printk("Unknown AHB divisor:0x%x\n", ahb); -+ ahbclk = 0; -+ } -+ -+ ahbclk = (int)ahb; -+} -+ -+int ag101_get_ahb_clk(void) -+{ -+ return ahbclk; -+} -+ -+EXPORT_SYMBOL(ag101_get_ahb_clk); -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/freq-scaling.c linux-3.4.113/arch/nds32/platforms/ag101/freq-scaling.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/freq-scaling.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/freq-scaling.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,367 @@ -+/* -+ * linux/arch/nds32/platforms/ag101/cpu-fcs.c -+ * -+ * Copyright (C) 2002,2003 Intrinsyc Software -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * History: -+ * 31-Jul-2002 : Initial version [FB] -+ * 29-Jan-2003 : added PXA255 support [FB] -+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) -+ * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.) -+ * -+ * Note: -+ * This driver may change the memory bus clock rate, but will not do any -+ * platform specific access timing changes... for example if you have flash -+ * memory connected to CS0, you will need to register a platform specific -+ * notifier which will adjust the memory access strobes to maintain a -+ * minimum strobe width. -+ * -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+#define NDS32_FCS_IRQ 8 -+#define AG101_MIN_FREQ 70000 -+#define AG101_MAX_FREQ 420000 -+#define OSC_KHZ 10000 /* 10 MHz AG101 */ -+ -+#define USE_CACHE 0 -+struct ag101_freq_struct { -+ -+ unsigned int khz; /* cpu_clk in khz */ -+ unsigned int sf; /* scaling factor */ -+ unsigned int cr; /* clock ratio */ -+}; -+ -+struct ag101_freq_struct ag101_run_freqs[] = { -+ -+ /* khz , sf, cr pll/cpu/ahb/apb */ -+ {AG101_MAX_FREQ / 6, 6, 1}, /* 420/070/070/035 */ -+ {AG101_MAX_FREQ / 1, 1, 6}, /* 420/420/070/035 */ -+ {0} -+}; -+ -+#define NUM_RUN_FREQS ARRAY_SIZE( ag101_run_freqs) -+static struct cpufreq_frequency_table ag101_run_freq_table[NUM_RUN_FREQS + 1]; -+ -+/* Use the turbo mode frequencies for the CPUFREQ_POLICY_POWERSAVE policy */ -+static struct ag101_freq_struct ag101_turbo_freqs[] = { -+ -+ /* khz , sf, cr pll/cpu/ahb/apb */ -+ {AG101_MAX_FREQ / 6, 6, 1}, /* 420/070/070/035 */ -+ {AG101_MAX_FREQ / 1, 1, 6}, /* 420/420/070/035 */ -+ {0} -+}; -+ -+#define NUM_TURBO_FREQS ARRAY_SIZE( ag101_turbo_freqs) -+static struct cpufreq_frequency_table ag101_turbo_freq_table[NUM_TURBO_FREQS + -+ 1]; -+ -+/* Generic helper function get CPU clocks in kHz */ -+unsigned int ag101_cpufreq_get(unsigned int dummy) -+{ -+ -+ unsigned int pll = (REG32(PMU_FTPMU010_VA_BASE + 0x30) >> 3UL) & 0x01ff; /* pll */ -+ unsigned int sf = (REG32(PMU_FTPMU010_VA_BASE + 0x0c) >> 8UL) & 0x0f; /* scaling factor */ -+ -+ return OSC_KHZ * pll / (sf + 1); -+} -+ -+/* find a valid frequency point */ -+static int ag101_verify_policy(struct cpufreq_policy *policy) -+{ -+ -+ struct cpufreq_frequency_table *ag101_freqs_table; -+ -+ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ -+ ag101_freqs_table = ag101_run_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ -+ ag101_freqs_table = ag101_turbo_freq_table; -+ } else { -+ printk -+ ("CPU PXA: Unknown policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ ag101_freqs_table = ag101_run_freq_table; -+ } -+ -+ printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min, -+ policy->max); -+ -+ return cpufreq_frequency_table_verify(policy, ag101_freqs_table); -+} -+ -+void start_fcs(unsigned int sf, unsigned cr) -+{ -+ -+ /* set EFSF in PMODE [11:8] */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(0xfUL << 8); -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (sf << 8); -+ -+ /* set EDIVAHBCLK [7:4] */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(0xffUL << 0); -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (cr << 4); -+ -+ /* PMR[1]: scaling mode */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) |= (1UL << 1); -+ -+ __asm__ __volatile__("msync all"); -+ __asm__ __volatile__("isb"); -+ __asm__ __volatile__("standby wake_grant"); -+ // REG32( PMU_FTPMU010_VA_BASE + 0x30) |= ( 1UL << 16); /* PDLLCR0 bit[16]==1:disable dll */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x0c) &= ~(1UL << 1); /* Power Mode Register */ -+} -+ -+void end_fcs(void) -+{ -+ -+ /* Leave this function as a place marker. */ -+} -+ -+static int cal_edivahbclk(int div) -+{ -+ -+ switch (div) { -+ -+ case 1: -+ case 2: -+ case 3: -+ case 4: -+ case 5: -+ case 6: -+ return --div; -+ case 8: -+ return 8; -+ case 10: -+ return 9; -+ case 12: -+ return 10; -+ case 14: -+ return 11; -+ case 15: -+ return 12; -+ case 18: -+ return 13; -+ case 20: -+ return 14; -+ default: -+ printk("Error: No such CPU/AHB frequency ratio %d", div); -+ } -+ -+ return 9; -+} -+ -+static int ag101_speedstep(int idx) -+{ -+ -+ unsigned int sf, cr; -+ unsigned long flags = 0; -+ void (*do_fcs) (unsigned int efsf, unsigned int edivhbaclk); -+ -+#if USE_CACHE -+ -+ int i; -+ int line_size = CACHE_LINE_SIZE(ICACHE); -+ unsigned long start = ((unsigned long)start_fcs) & ~(line_size - 1); -+ unsigned long end = -+ (((unsigned long)end_fcs) + line_size) & ~(line_size - 1); -+ -+ printk("&start_fcs(): 0x%08lx, aligned to: 0x%08lx\n", -+ (unsigned long)start_fcs, start); -+ printk("&end_fcs(): 0x%08lx, aligned to: 0x%08lx\n", -+ (unsigned long)end_fcs, end); -+ -+ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK":: -+ "r" (i):"memory"); -+ -+ do_fcs = start_fcs; -+#else -+ unsigned long buf, aligned_buf, len = PAGE_SIZE; -+ -+ buf = (unsigned long)kmalloc(0x100000 + 1000, GFP_KERNEL); -+ if (!buf) -+ printk("Error: kmalloc( base) failed\n"); -+ -+ aligned_buf = (buf + 0x100000 - 1) & 0xFFF00000; -+ -+ if (sys_lmmap(LM_ILM, aligned_buf, aligned_buf + 0x1000, 0, NULL)) { -+ printk("Error: lmmap failed, can't scale frequency.\n"); -+#ifdef CONFIG_CPU_FREQ_DEBUG -+ WARN_ON(1); -+#endif -+ return 0; -+ } -+ -+ if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 9) -+ len = 0x400; -+ else if (((GET_ILMB() & ILMB_mskILMSZ) >> ILMB_offILMSZ) == 10) -+ len = 0x800; -+ memcpy((unsigned char *)aligned_buf, (unsigned char *)start_fcs, len); -+ -+ do_fcs = (void *)aligned_buf; -+#endif -+ sf = ag101_run_freqs[idx].sf - 1; -+ cr = cal_edivahbclk(ag101_run_freqs[idx].cr); -+ -+ local_irq_save(flags); -+ do_fcs(sf, cr); -+ local_irq_restore(flags); -+ -+#if USE_CACHE -+ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory"); -+#else -+ if (sys_lmunmap(aligned_buf, 0)) -+ printk("Error: lmunmap failed\n"); -+ -+ kfree((void *)buf); -+#endif -+ return 1; -+} -+ -+static int ag101_set_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, unsigned int relation) -+{ -+ -+ unsigned int idx; -+ struct cpufreq_frequency_table *ag101_freqs_table; -+ struct ag101_freq_struct *ag101_freq_settings; -+ struct cpufreq_freqs freqs; -+ -+ /* Get the current policy */ -+ if (policy->policy == CPUFREQ_POLICY_PERFORMANCE) { -+ -+ ag101_freq_settings = ag101_run_freqs; -+ ag101_freqs_table = ag101_run_freq_table; -+ } else if (policy->policy == CPUFREQ_POLICY_POWERSAVE) { -+ -+ ag101_freq_settings = ag101_turbo_freqs; -+ ag101_freqs_table = ag101_turbo_freq_table; -+ } else { -+ printk -+ ("Unknown FCS policy found. Using CPUFREQ_POLICY_PERFORMANCE\n"); -+ ag101_freq_settings = ag101_run_freqs; -+ ag101_freqs_table = ag101_run_freq_table; -+ } -+ -+ /* Lookup the next frequency */ -+ if (cpufreq_frequency_table_target -+ (policy, ag101_freqs_table, target_freq, relation, &idx)) -+ return -EINVAL; -+ -+ freqs.old = policy->cur; -+ freqs.new = ag101_freq_settings[idx].khz; -+ freqs.cpu = policy->cpu; -+ -+ /* -+ * Tell everyone what we're about to do... -+ * you should add a notify client with any platform specific -+ * Vcc changing capability -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+ if (freqs.new != freqs.old) { -+ -+ if (!ag101_speedstep(idx)) -+ return -ENODEV; -+ } -+ -+ /* -+ * Tell everyone what we've just done... -+ * you should add a notify client with any platform specific -+ * SDRAM refresh timer adjustments -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+ -+ return 0; -+} -+ -+static int ag101_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ -+ int i; -+ /* set default policy and cpuinfo */ -+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; -+ policy->policy = CPUFREQ_POLICY_PERFORMANCE; -+ policy->cpuinfo.max_freq = AG101_MAX_FREQ; -+ policy->cpuinfo.min_freq = AG101_MIN_FREQ; -+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ -+ policy->cur = ag101_cpufreq_get(0); /* current freq */ -+ policy->min = policy->max = policy->cur; -+ -+ /* Generate the run cpufreq_frequency_table struct */ -+ for (i = 0; i < NUM_RUN_FREQS; i++) { -+ -+ ag101_run_freq_table[i].frequency = ag101_run_freqs[i].khz; -+ ag101_run_freq_table[i].index = i; -+ } -+ -+ ag101_run_freq_table[i].frequency = CPUFREQ_TABLE_END; -+ -+ /* Generate the turbo cpufreq_frequency_table struct */ -+ for (i = 0; i < NUM_TURBO_FREQS; i++) { -+ -+ ag101_turbo_freq_table[i].frequency = ag101_turbo_freqs[i].khz; -+ ag101_turbo_freq_table[i].index = i; -+ } -+ -+ ag101_turbo_freq_table[i].frequency = CPUFREQ_TABLE_END; -+ -+ printk("CPU frequency change support initialized\n"); -+ -+ return 0; -+} -+ -+static struct cpufreq_driver ag101_cpufreq_driver = { -+ -+ .verify = ag101_verify_policy, -+ .target = ag101_set_target, -+ .init = ag101_cpufreq_init, -+ .get = ag101_cpufreq_get, -+ .name = "AG101", -+}; -+ -+static int __init ag101_cpu_init(void) -+{ -+ -+ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) -+ return cpufreq_register_driver(&ag101_cpufreq_driver); -+ else -+ return -ENODEV; -+} -+ -+static void __exit ag101_cpu_exit(void) -+{ -+ -+ if (CPU_IS_N1213_43U1HA0() || CPU_IS_N1213_43U1HB0()) -+ cpufreq_unregister_driver(&ag101_cpufreq_driver); -+} -+ -+MODULE_AUTHOR("Andes Technology Corporation"); -+MODULE_DESCRIPTION("CPU frequency changing driver for the AG101 architecture"); -+MODULE_LICENSE("GPL"); -+module_init(ag101_cpu_init); -+module_exit(ag101_cpu_exit); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/Kconfig linux-3.4.113/arch/nds32/platforms/ag101/Kconfig ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/Kconfig 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,9 @@ -+menu "AG101 Platform Options" -+ -+config AUTO_SYS_CLK -+ bool "Automatic AHB Clock Detection" -+ default y -+ help -+ Automatic detection of AHB clock -+ -+endmenu -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/Makefile linux-3.4.113/arch/nds32/platforms/ag101/Makefile ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/Makefile 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,5 @@ -+obj-y = devices.o -+obj-$(CONFIG_AUTO_SYS_CLK) += fia320.o -+obj-$(CONFIG_PM) += pm.o sleep.o -+obj-$(CONFIG_AG101_CPU_FREQ_FCS) += cpu-fcs.o -+obj-$(CONFIG_AG101_CPU_FREQ_SCALING_MODE) += freq-scaling.o -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/pm.c linux-3.4.113/arch/nds32/platforms/ag101/pm.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/pm.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/pm.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,190 @@ -+/* -+ * AG101 Power Management Routines -+ * -+ * Copyright (c) 2007 Harry Pan -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License. -+ * -+ * Abstract: -+ * -+ * This program is for AG101 power management routines. -+ * It is initail referred from 2.6.11 SA1100 PM driver. -+ * -+ * Revision History: -+ * -+ * Jul.13.2007 Initial code by Harry. -+ */ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+ -+extern void ag101_cpu_sleep(void); -+extern void ag101_cpu_resume(void); -+extern void ag101_cpu_resume2(void); -+ -+#include -+/* -+ * AG101 PMU sleep mode handler. -+ */ -+void ag101_pmu_sleep(void) -+{ -+ int i; -+ static int irq_saves[3]; -+ -+ irq_saves[0] = REG32(INTC_FTINTC010_VA_BASE + 0x4); -+ irq_saves[1] = REG32(INTC_FTINTC010_VA_BASE + 0xc); -+ irq_saves[2] = REG32(INTC_FTINTC010_VA_BASE + 0x10); -+ -+ /* save SDRAM settings */ -+ for (i = 0; i < 0x30; i += 4) -+ REG32(PMU_FTPMU010_VA_BASE + 0x50 + i) = REG32(SDMC_FTSDMC021_VA_BASE + i); //SDRAMC -+ -+ /* set resume return address */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x88) = -+ virt_to_phys(ag101_cpu_resume) | 0x10000000; -+ REG32(PMU_FTPMU010_VA_BASE + 0x8c) = (u32) ag101_cpu_resume2; -+ REG32(PMU_FTPMU010_VA_BASE + 0x80) = GET_L1_PPTB(); -+ -+ /* setup wakeup sources */ -+ REG32(PMU_FTPMU010_VA_BASE + 0x14) |= -1; -+ REG32(PMU_FTPMU010_VA_BASE + 0x10) |= 0x1fff; -+ -+ cpu_dcache_wbinval_all(); -+ cpu_icache_inval_all(); -+ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN); -+ ag101_cpu_sleep(); -+ -+#ifndef CONFIG_ANDES_PAGE_SIZE_8KB -+ -+ if (CPU_IS_N1213_43U1HA0()) { -+ int tmp = 0; -+ /* Downsize cache to bypass cache aliasing issue */ -+ -+ if ((CACHE_SET(ICACHE) * CACHE_LINE_SIZE(ICACHE)) > 4096) -+ tmp = 0x02 << SDZ_CTL_offICDZ; -+ -+ if ((CACHE_SET(DCACHE) * CACHE_LINE_SIZE(DCACHE)) > 4096) -+ tmp |= 0x02 << SDZ_CTL_offDCDZ; -+ -+ SET_SDZ_CTL(tmp); -+ ISB(); -+ } -+#endif -+ -+ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN); -+ REG32(INTC_FTINTC010_VA_BASE + 0x4) = irq_saves[0]; -+ REG32(INTC_FTINTC010_VA_BASE + 0xc) = irq_saves[1]; -+ REG32(INTC_FTINTC010_VA_BASE + 0x10) = irq_saves[2]; -+} -+ -+static int ag101_pm_valid(suspend_state_t state) -+{ -+ switch (state) { -+ case PM_SUSPEND_ON: -+ case PM_SUSPEND_STANDBY: -+ case PM_SUSPEND_MEM: -+ return 1; -+ -+ default: -+ return 0; -+ } -+} -+ -+static int ag101_pm_begin(suspend_state_t state) -+{ -+ /* TBD if we need it */ -+ return 0; -+} -+ -+static unsigned long irq_save; -+static inline void setup_wakeup_event(void) -+{ -+ REG32(GPIO_FTGPIO010_VA_BASE + 0x20) = 1; -+ irq_save = REG32(INTC_FTINTC010_VA_BASE + 0x4); -+ REG32(INTC_FTINTC010_VA_BASE + 0x4) &= ~(1 << 19); -+ REG32(INTC_FTINTC010_VA_BASE + 0x4) |= 1 << 13; -+} -+ -+static inline void remove_wakeup_event(void) -+{ -+ REG32(GPIO_FTGPIO010_VA_BASE + 0x30) = 1; -+ REG32(GPIO_FTGPIO010_VA_BASE + 0x20) = 0; -+ REG32(INTC_FTINTC010_VA_BASE + 0x4) = irq_save; -+} -+ -+static inline void cpu_standby(void) -+{ -+ asm __volatile__("standby no_wake_grant"); -+} -+ -+static int ag101_pm_enter(suspend_state_t state) -+{ -+ switch (state) { -+ case PM_SUSPEND_STANDBY: -+ setup_wakeup_event(); -+ cpu_standby(); -+ remove_wakeup_event(); -+ return 0; -+ case PM_SUSPEND_MEM: -+ ag101_pmu_sleep(); -+ return 0; -+ default: -+ return -EINVAL; -+ } -+} -+ -+/* -+ * Called after processes are frozen, but before we shutdown devices. -+ */ -+static int ag101_pm_prepare(void) -+{ -+ /* TBD if we need it */ -+ return 0; -+} -+ -+/* -+ * Called after devices are wakeuped, but before processes are thawed. -+ */ -+static void ag101_pm_finish(void) -+{ -+ /* TBD if we need it */ -+} -+ -+static void ag101_pm_end(void) -+{ -+ /* TBD if we need it */ -+} -+ -+/* -+ * Set to PM_DISK_FIRMWARE so we can quickly veto suspend-to-disk. -+ */ -+static struct platform_suspend_ops ag101_pm_ops = { -+ .valid = ag101_pm_valid, -+ .begin = ag101_pm_begin, -+ .prepare = ag101_pm_prepare, -+ .enter = ag101_pm_enter, -+ .finish = ag101_pm_finish, -+ .end = ag101_pm_end, -+}; -+ -+static int __init ag101_pm_init(void) -+{ -+ printk("PM driver init\n"); -+ suspend_set_ops(&ag101_pm_ops); -+ REG32(GPIO_FTGPIO010_VA_BASE + 0x30) = 1; -+ REG32(INTC_FTINTC010_VA_BASE + 0x0c) &= ~(1 << 13); -+ REG32(INTC_FTINTC010_VA_BASE + 0x10) &= ~(1 << 13); -+ -+ return 0; -+} -+ -+late_initcall(ag101_pm_init); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101/sleep.S linux-3.4.113/arch/nds32/platforms/ag101/sleep.S ---- linux-3.4.113.orig/arch/nds32/platforms/ag101/sleep.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101/sleep.S 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,118 @@ -+/* -+ * AG101 Assembler Sleep/WakeUp Management Routines -+ * -+ * Copyright (c) 2007 Harry Pan -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License. -+ * -+ * Abstract: -+ * -+ * This program is for AG101 suspend/wakeup. -+ * -+ * Revision History: -+ * -+ * Jul.13.2007 Initial code by Harry. -+ */ -+#include -+#include -+#include -+#include -+ -+ .text -+ -+/* ag101_cpu_suspend() -+ * -+ * Causes AG101 to enter sleep state -+ */ -+ -+ENTRY(ag101_cpu_sleep) -+ pushm $r0, $r30 -+ mfusr $r0, $d0.lo ! $d0 lo byte -+ mfusr $r1, $d0.hi ! $d0 hi byte -+ mfusr $r2, $d1.lo ! $d1 lo byte -+ mfusr $r3, $d1.hi ! $d1 hi byte -+ mfsr $r4, $mr0 -+ mfsr $r5, $mr1 -+ mfsr $r6, $mr4 -+ mfsr $r7, $mr6 -+ mfsr $r8, $mr7 -+ mfsr $r9, $mr8 -+ mfsr $r10, $ir0 -+ mfsr $r11, $ir1 -+ mfsr $r12, $ir2 -+ mfsr $r13, $ir3 -+ mfsr $r14, $ir9 -+ mfsr $r15, $ir10 -+ mfsr $r16, $ir12 -+ mfsr $r17, $ir13 -+ mfsr $r18, $ir14 -+ mfsr $r19, $ir15 -+ pushm $r0, $r19 -+ -+ sethi $r0, hi20(PMU_FTPMU010_0_VA_BASE + 0x84) -+ ori $r2, $r0, lo12(PMU_FTPMU010_0_VA_BASE + 0x84) -+ swi $r31, [$r2] -+ -+ lwi $r2, [$r0+#0x0c] ! sleep mode -+ ori $r2, $r2, #1 -+ swi $r2, [$r0+#0x0c] ! sleep mode -+ standby wake_grant -+1: -+ b 1b ! loop waiting for sleep -+ -+/* ag101_cpu_resume() -+ * -+ * Entry point from boot code back to kernel. -+ * -+ */ -+ -+ENTRY(ag101_cpu_resume) -+ mfsr $r2, $mr0 -+ ori $r2, $r2, #0x6 -+#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -+ ori $r2, $r2, #0x1 -+#endif -+ mtsr $r2, $mr0 -+ -+ sethi $r2, hi20(PMU_FTPMU010_0_PA_BASE + 0x80) -+ ori $r2, $r2, lo12(PMU_FTPMU010_0_PA_BASE + 0x80) -+ lwi $r3, [$r2] -+ lwi $r4, [$r2 + 0xc] -+ mtsr $r3, $mr1 -+ -+ mfsr $r0, $mr8 -+ ori $r0, $r0, #0x1 -+ mtsr $r0, $mr8 -+ -+ sethi $r2, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x88) -+ ori $r2, $r2, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x88) -+ movi $r3, #0x1 -+ swi $r3, [$r2] -+ -+ jral.ton $r4, $r4 -+ -+ENTRY(ag101_cpu_resume2) -+ popm $r0, $r19 -+ mtusr $r0, $d0.lo ! $d0 lo byte -+ mtusr $r1, $d0.hi ! $d0 hi byte -+ mtusr $r2, $d1.lo ! $d1 lo byte -+ mtusr $r3, $d1.hi ! $d1 hi byte -+ mtsr $r4, $mr0 -+ mtsr $r5, $mr1 -+ mtsr $r6, $mr4 -+ mtsr $r7, $mr6 -+ mtsr $r8, $mr7 -+ mtsr $r9, $mr8 -+ mtsr $r10, $ir0 -+ mtsr $r11, $ir1 -+ mtsr $r12, $ir2 -+ mtsr $r13, $ir3 -+ mtsr $r14, $ir9 -+ mtsr $r15, $ir10 -+ mtsr $r16, $ir12 -+ mtsr $r17, $ir13 -+ mtsr $r18, $ir14 -+ mtsr $r19, $ir15 -+ popm $r0, $r30 -+ ret -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101p/devices.c linux-3.4.113/arch/nds32/platforms/ag101p/devices.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101p/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101p/devices.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,104 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+const struct map_desc platform_io_desc[] __initdata = { -+ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, -+ PAGE_SIZE, MT_DEVICE_NCB}, -+ {USB_FOTG2XX_0_VA_BASE, USB_FOTG2XX_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, (0x000FF000 & PAGE_MASK), -+ MT_DEVICE_NCB}, -+ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {AHB_ATFAHBC020S_0_VA_BASE, AHB_ATFAHBC020S_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} -+}; -+ -+static void __init platform_map_io(void) -+{ -+ iotable_init((struct map_desc *)platform_io_desc, -+ ARRAY_SIZE(platform_io_desc)); -+} -+ -+static struct uart_port uart0 = { -+ .membase = (void __iomem *)UART0_VA_BASE, -+ .irq = UART0_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 0, -+ .mapbase = UART0_PA_BASE, -+}; -+ -+static struct uart_port uart1 = { -+ .membase = (void __iomem *)UART1_VA_BASE, -+ .irq = UART1_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 1, -+ .mapbase = UART1_PA_BASE, -+}; -+ -+static void __init soc_init(void) -+{ -+ early_serial_setup(&uart0); -+ early_serial_setup(&uart1); -+} -+ -+MACHINE_START(FARADAY, PLATFORM_NAME) -+ .param_offset = BOOT_PARAMETER_PA_BASE, -+ .map_io = platform_map_io, -+ .init_irq = platform_init_irq, -+ .timer = &platform_timer, /* defined in timer.c */ -+ .init_machine = soc_init, -+MACHINE_END static struct platform_device usb_dev_otg_host = { -+ .name = "fotg-ehci", -+}; -+ -+static int __init fotg_init(void) -+{ -+ platform_device_register(&usb_dev_otg_host); -+ return 0; -+} -+ -+device_initcall(fotg_init); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101p/interrupt-latency.c linux-3.4.113/arch/nds32/platforms/ag101p/interrupt-latency.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag101p/interrupt-latency.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101p/interrupt-latency.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,197 @@ -+/* -+ * interrupt_latency v1.0 11/25/01 -+ * www.embeddedlinuxinterfacing.com -+ * -+ * The original location of this code is -+ * http://www.embeddedlinuxinterfacing.com/chapters/11/ -+ * -+ * Copyright (C) 2001 by Craig Hollabaugh -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU Library 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 -+ * Library General Public License for more details. -+ * -+ * You should have received a copy of the GNU Library 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 -+ */ -+ -+/* -+ * interrupt_latency.c is based on procfs_example.c by Erik Mouw. -+ * For more information, please see, The Linux Kernel Procfs Guide, Erik Mouw -+ * http://kernelnewbies.org/documents/kdoc/procfs-guide/lkprocfsguide.html -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define ILT_MODULE_VERSION "1.0" -+#define MODULE_NAME "interrupt_latency" -+ -+#define USE_PFM -+static int interruptcount = 0; -+#ifdef USE_PFM -+static unsigned int start_cycle = 0, finish_cycle = 0; -+static unsigned int start_inst = 0, finish_inst = 0; -+static unsigned int start_int = 0, finish_int = 0; -+#else -+static struct timeval tv1, tv2; /* do_gettimeofday fills these */ -+#endif -+ -+#define INTERRUPT 9 -+ -+static struct proc_dir_entry *interrupt_latency_file; -+ -+/* -+ * function interrupt_interrupt_latency -+ * This function is the interrupt handler for interrupt 7. It sets the tv2 -+ * structure using do_gettimeofday. It then deasserts D7. -+ */ -+static irqreturn_t interrupt_interrupt_latency(int irq, void *dev_id) -+{ -+ unsigned int ir15, pfm_ctl; -+#ifdef USE_PFM -+ /* disable counter */ -+ pfm_ctl = 0x4410000; //cycles, instructions and icache misses -+ //pfm_ctl = 0x4c0000; //instructions and interrupts -+ //pfm_ctl = 0x4510000; //icache accesses and misses -+ __nds32__mtsr(pfm_ctl, NDS32_SR_PFM_CTL); //instructions and interrupts -+ finish_cycle = __nds32__mfsr(NDS32_SR_PFMC0); -+ finish_inst = __nds32__mfsr(NDS32_SR_PFMC2); -+ finish_int = __nds32__mfsr(NDS32_SR_PFMC1); -+#else -+ do_gettimeofday(&tv2); -+#endif -+ /* deassert the interrupt signal */ -+ ir15 = __nds32__mfsr(NDS32_SR_INT_PEND); -+ __nds32__mtsr((~0x10000) & ir15, NDS32_SR_INT_PEND); -+ __nds32__dsb(); -+ -+ interruptcount++; -+ return IRQ_HANDLED; -+} -+ -+/* -+ * function proc_read_interrupt_latency -+ * The kernel executes this function when a read operation occurs on -+ * /proc/interrupt_latency. This function sets the tv1 structure. It asserts -+ * D7 which should immediately cause interrupt 7 to occur. The handler -+ * records tv2 and deasserts D7. This function returns the time differential -+ * between tv2 and tv1. -+ */ -+static int proc_read_interrupt_latency(char *page, char **start, off_t off, -+ int count, int *eof, void *data) -+{ -+ int len; -+ unsigned int ir15, pfm_ctl; -+#ifdef USE_PFM -+ //pfm_ctl = 0x4c0007; -+ //pfm_ctl = 0x4510007; -+ pfm_ctl = 0x4410007; -+ start_cycle = __nds32__mfsr(NDS32_SR_PFMC0); -+ start_inst = __nds32__mfsr(NDS32_SR_PFMC2); -+ start_int = __nds32__mfsr(NDS32_SR_PFMC1); -+ __nds32__mtsr(pfm_ctl, NDS32_SR_PFM_CTL); -+#else -+ do_gettimeofday(&tv1); -+#endif -+ /* assert the interrupt signal */ -+ ir15 = __nds32__mfsr(NDS32_SR_INT_PEND); -+ __nds32__mtsr(0x10000 | ir15, NDS32_SR_INT_PEND); -+ __nds32__dsb(); -+ -+#ifdef USE_PFM -+ len = -+ sprintf(page, -+ "Cnt0 %11u Start %11u Finish %11u Cycles %11u\n" -+ "Cnt2 %11u Start %11u Finish %11u icache miss %11u\n" -+ "Cnt1 %11u Start %11u Finish %11u Instructions %11u\n" -+ "Count %11i\n", ((pfm_ctl & 0x8000) >> 15), start_cycle, -+ finish_cycle, (finish_cycle - start_cycle), -+ ((pfm_ctl & 0xfc00000) >> 22), start_inst, finish_inst, -+ (finish_inst - start_inst), ((pfm_ctl & 0x3f0000) >> 16), -+ start_int, finish_int, (finish_int - start_int), -+ interruptcount); -+#else -+ len = sprintf(page, "Start %9i.%06i\nFinish %9i.%06i\nLatency %17i\n\ -+Count %19i\n", (int)tv1.tv_sec, (int)tv1.tv_usec, (int)tv2.tv_sec, (int)tv2.tv_usec, (int)(tv2.tv_usec - tv1.tv_usec), interruptcount); -+#endif -+ *eof = 1; -+ return len; -+} -+ -+/* -+ * function init_interrupt_latency -+ * This function creates the /proc directory entry interrupt_latency. It -+ * also configures the parallel port then requests interrupt 7 from Linux. -+ */ -+static int __init init_interrupt_latency(void) -+{ -+ int rv = 0; -+ unsigned int ir14; -+ -+ interrupt_latency_file = -+ create_proc_entry("interrupt_latency", 0444, NULL); -+ if (interrupt_latency_file == NULL) { -+ return -ENOMEM; -+ } -+ -+ interrupt_latency_file->data = NULL; -+ interrupt_latency_file->read_proc = &proc_read_interrupt_latency; -+ interrupt_latency_file->write_proc = NULL; -+ -+ /* request interrupt from linux */ -+ rv = request_irq(INTERRUPT, interrupt_interrupt_latency, IRQF_DISABLED, -+ "interrupt_latency", (void *)NULL); -+ if (rv) { -+ printk("Can't get interrupt %d\n", INTERRUPT); -+ goto no_interrupt_latency; -+ } -+ -+ /* unmask SWI */ -+ ir14 = __nds32__mfsr(NDS32_SR_INT_MASK); -+ __nds32__mtsr((0x10000 | ir14), NDS32_SR_INT_MASK); -+ __nds32__dsb(); -+ -+ /* everything initialized */ -+ printk(KERN_INFO "%s %s initialized\n", MODULE_NAME, -+ ILT_MODULE_VERSION); -+ return 0; -+ -+ /* remove the proc entry on error */ -+no_interrupt_latency: -+ remove_proc_entry("interrupt_latency", NULL); -+ return 0; -+} -+ -+/* -+ * function cleanup_interrupt_latency -+ * This function frees interrupt then removes the /proc directory entry -+ * interrupt_latency. -+ */ -+static void __exit cleanup_interrupt_latency(void) -+{ -+ /* free the interrupt */ -+ free_irq(INTERRUPT, (void *)NULL); -+ -+ remove_proc_entry("interrupt_latency", NULL); -+ -+ printk(KERN_INFO "%s %s removed\n", MODULE_NAME, ILT_MODULE_VERSION); -+} -+ -+module_init(init_interrupt_latency); -+module_exit(cleanup_interrupt_latency); -+ -+MODULE_DESCRIPTION("interrupt_latency proc module"); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101p/Kconfig linux-3.4.113/arch/nds32/platforms/ag101p/Kconfig ---- linux-3.4.113.orig/arch/nds32/platforms/ag101p/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101p/Kconfig 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,11 @@ -+menu "AG101P Platform Options" -+config CACHE_L2 -+bool "Support L2 cache" -+ default n -+ -+config MEASURE_INTERRUPT_LATENCY -+ bool "Measure interrupt latency" -+ default n -+ help -+ Enable measuring interrupt latency with software interrupt -+endmenu -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag101p/Makefile linux-3.4.113/arch/nds32/platforms/ag101p/Makefile ---- linux-3.4.113.orig/arch/nds32/platforms/ag101p/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag101p/Makefile 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,2 @@ -+obj-y = devices.o -+obj-$(CONFIG_MEASURE_INTERRUPT_LATENCY) += interrupt-latency.o -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/ahbclkcal.c linux-3.4.113/arch/nds32/platforms/ag102/ahbclkcal.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/ahbclkcal.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/ahbclkcal.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,216 @@ -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#ifdef CONFIG_AUTO_SYS_CLK -+ -+#define OSCH3_CLK 33000000 -+#define OSCH_CLK 25000000 -+#define MHZ 1000000 -+/* -+ * Table for ahb divisor, PMODE[07:04] -+ */ -+static const int ahb_div[16] = { -+ 1, 2, 3, 4, 5, 6, 3, 5, -+ 8, 10, 12, 14, 15, 18, 20, -1 -+}; -+ -+/* ag102_get_ahb_clk() -+ * -+ * return AHB clock in Hz. -+ */ -+static int ahbclk; -+void ag102_calc_ahb_clk(void) -+{ -+ unsigned int pcs1_param; -+ unsigned int pcs4_param; -+ unsigned int pcs5_param; -+ unsigned int main_PLL_div; -+ unsigned int main_PLL_out; -+ unsigned int ratio; -+ unsigned int main_PLL_N; -+ unsigned int main_PLL_M = 1; -+ unsigned int F_core0; -+ unsigned int F_core1; -+ unsigned int F_l2cc; -+ unsigned int F_ddr2; -+ unsigned int F_ahb; -+ unsigned int F_apb; -+ unsigned int F_pci; -+ -+ pcs1_param = REG32(PCU_VA_BASE + 0xa4); //pcs1 parameter register, for core/ahb/apb clk ratio setting -+ main_PLL_div = (pcs1_param >> 4) & 0x3; -+ ratio = pcs1_param & 0xf; -+ -+ pcs4_param = REG32(PCU_VA_BASE + 0x104); //pcs4 parameter register, for main PLL setting -+ main_PLL_N = pcs4_param & 0xff; -+ main_PLL_out = (OSCH3_CLK * main_PLL_N / main_PLL_M) >> main_PLL_div; -+ -+ pcs5_param = REG32(PCU_VA_BASE + 0x124); //pcs5 parameter register, for PCI PLL/DLL setting -+ -+ switch (ratio) { -+ case 0: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 1: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 2: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 1; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 3: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 1; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 4: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 2; -+ F_l2cc = F_core0 >> 2; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ case 5: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 2; -+ F_l2cc = F_core0 >> 2; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 6: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 7: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0; -+ F_ddr2 = F_core0 >> 1; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 8: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = OSCH_CLK * 24 / 2; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 9: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = OSCH_CLK * 24 / 2; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ case 10: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 1; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = OSCH_CLK * 24 / 2; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 11: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 1; -+ F_l2cc = F_core0 >> 1; -+ F_ddr2 = OSCH_CLK * 24 / 2; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 12: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 2; -+ F_l2cc = F_core0 >> 2; -+ F_ddr2 = OSCH_CLK * 24 / 2; -+ F_ahb = F_core0 >> 2; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 13: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0 >> 2; -+ F_l2cc = F_core0 >> 2; -+ F_ddr2 = OSCH_CLK * 24 / 2; -+ F_ahb = F_core0 >> 3; -+ F_apb = F_ahb >> 1; -+ break; -+ -+ case 14: -+ F_core0 = main_PLL_out; -+ F_core1 = F_core0; -+ F_l2cc = F_core0; -+ F_ddr2 = F_core0; -+ F_ahb = F_core0; -+ F_apb = F_ahb; -+ break; -+ default: // 15 -+ F_core0 = OSCH3_CLK; -+ F_core1 = F_core0; -+ F_l2cc = F_core0; -+ F_ddr2 = F_core0; -+ F_ahb = F_core0; -+ F_apb = F_ahb; -+ break; -+ } -+ -+ F_pci = OSCH_CLK * 24 / 9; -+ if ((pcs5_param & 0x800) == 0) -+ F_pci = F_pci >> 1; -+ -+ ahbclk = (int)F_ahb; -+} -+ -+int ag102_get_ahb_clk(void) -+{ -+ //return ahbclk+MHZ; -+ return ahbclk; -+} -+ -+EXPORT_SYMBOL(ag102_get_ahb_clk); -+#else -+void ag102_calc_ahb_clk(void) -+{ -+} -+#endif -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/devices.c linux-3.4.113/arch/nds32/platforms/ag102/devices.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/devices.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,181 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+extern void amic_init(void); -+ -+const struct map_desc platform_io_desc[] __initdata = { -+ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {AMIC_VA_BASE, AMIC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {GMAC_VA_BASE, GMAC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {APBBR_VA_BASE, APBBR_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {TIMER_VA_BASE, TIMER_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x0000F000, MT_DEVICE_NCB}, -+ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {PCU_VA_BASE, PCU_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {LPC_IO_VA_BASE, LPC_IO_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {LPC_REG_VA_BASE, LPC_REG_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {GPU_VA_BASE, GPU_PA_BASE, SZ_64K, MT_DEVICE_NCB}, -+ {IDE_FTIDE020_VA_BASE, IDE_FTIDE020_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {USB_FOTG2XX_0_VA_BASE, USB_FOTG2XX_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SPI_FTSSP010_0_VA_BASE, SPI_FTSSP010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {DDR2C_VA_BASE, DDR2C_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {AHB_ATFAHBC020S_0_VA_BASE, AHB_ATFAHBC020S_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB} -+ //{ GPIO_VA_BASE, GPIO_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB } -+}; -+ -+/* hid descriptor for a keyboard */ -+static struct hidg_func_descriptor my_hid_data = { -+ .subclass = 0, /* No subclass */ -+ .protocol = 1, /* Keyboard */ -+ .report_length = 8, -+ .report_desc_length = 63, -+ .report_desc = { -+ 0x05, 0x01, /* USAGE_PAGE (Generic Desktop) */ -+ 0x09, 0x06, /* USAGE (Keyboard) */ -+ 0xa1, 0x01, /* COLLECTION (Application) */ -+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ -+ 0x19, 0xe0, /* USAGE_MINIMUM (Keyboard LeftControl) */ -+ 0x29, 0xe7, /* USAGE_MAXIMUM (Keyboard Right GUI) */ -+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ -+ 0x25, 0x01, /* LOGICAL_MAXIMUM (1) */ -+ 0x75, 0x01, /* REPORT_SIZE (1) */ -+ 0x95, 0x08, /* REPORT_COUNT (8) */ -+ 0x81, 0x02, /* INPUT (Data,Var,Abs) */ -+ 0x95, 0x01, /* REPORT_COUNT (1) */ -+ 0x75, 0x08, /* REPORT_SIZE (8) */ -+ 0x81, 0x03, /* INPUT (Cnst,Var,Abs) */ -+ 0x95, 0x05, /* REPORT_COUNT (5) */ -+ 0x75, 0x01, /* REPORT_SIZE (1) */ -+ 0x05, 0x08, /* USAGE_PAGE (LEDs) */ -+ 0x19, 0x01, /* USAGE_MINIMUM (Num Lock) */ -+ 0x29, 0x05, /* USAGE_MAXIMUM (Kana) */ -+ 0x91, 0x02, /* OUTPUT (Data,Var,Abs) */ -+ 0x95, 0x01, /* REPORT_COUNT (1) */ -+ 0x75, 0x03, /* REPORT_SIZE (3) */ -+ 0x91, 0x03, /* OUTPUT (Cnst,Var,Abs) */ -+ 0x95, 0x06, /* REPORT_COUNT (6) */ -+ 0x75, 0x08, /* REPORT_SIZE (8) */ -+ 0x15, 0x00, /* LOGICAL_MINIMUM (0) */ -+ 0x25, 0x65, /* LOGICAL_MAXIMUM (101) */ -+ 0x05, 0x07, /* USAGE_PAGE (Keyboard) */ -+ 0x19, 0x00, /* USAGE_MINIMUM (Reserved) */ -+ 0x29, 0x65, /* USAGE_MAXIMUM (Keyboard Application) */ -+ 0x81, 0x00, /* INPUT (Data,Ary,Abs) */ -+ 0xc0 /* END_COLLECTION */ -+ } -+}; -+ -+static struct platform_device my_hid = { -+ .name = "hidg", -+ .id = 0, -+ .num_resources = 0, -+ .resource = 0, -+ .dev.platform_data = &my_hid_data, -+}; -+ -+static void __init platform_map_io(void) -+{ -+ iotable_init((struct map_desc *)platform_io_desc, -+ ARRAY_SIZE(platform_io_desc)); -+} -+ -+static struct resource ftgmac100_resources[] = { -+ [0] = { -+ .start = GMAC_PA_BASE, -+ .end = GMAC_PA_BASE + SZ_4K - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = GMAC_IRQ, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device ftgmac100_device = { -+ .name = "ftgmac100", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(ftgmac100_resources), -+ .resource = ftgmac100_resources, -+}; -+ -+static int __init devices_init(void) -+{ -+ platform_device_register(&ftgmac100_device); -+ platform_device_register(&my_hid); -+ return 0; -+} -+ -+arch_initcall(devices_init); -+ -+static struct uart_port uart0 = { -+ .membase = (void __iomem *)UART0_VA_BASE, -+ .irq = UART0_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 0, -+ .mapbase = UART0_PA_BASE, -+}; -+ -+static struct uart_port uart1 = { -+ .membase = (void __iomem *)UART1_VA_BASE, -+ .irq = UART1_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 1, -+ .mapbase = UART1_PA_BASE, -+}; -+ -+void ag102_calc_ahb_clk(void); -+static void __init soc_init(void) -+{ -+ ag102_calc_ahb_clk(); -+ early_serial_setup(&uart0); -+ early_serial_setup(&uart1); -+} -+ -+MACHINE_START(FARADAY, PLATFORM_NAME) -+ .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = amic_init,.timer = &platform_timer, /* defined in timer.c */ -+.init_machine = soc_init, -+ MACHINE_END static struct platform_device usb_dev_otg_host = { -+ .name = "fotg-ehci", -+}; -+ -+static int __init fotg_init(void) -+{ -+ platform_device_register(&usb_dev_otg_host); -+ return 0; -+} -+ -+device_initcall(fotg_init); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/freq-scaling.c linux-3.4.113/arch/nds32/platforms/ag102/freq-scaling.c ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/freq-scaling.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/freq-scaling.c 2016-12-01 20:59:24.372613522 +0100 -@@ -0,0 +1,512 @@ -+/* -+ * linux/arch/nds32/platforms/ag102/cpu-fcs.c -+ * -+ * Copyright (C) 2002,2003 Intrinsyc Software -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * History: -+ * 31-Jul-2002 : Initial version [FB] -+ * 29-Jan-2003 : added PXA255 support [FB] -+ * 20-Apr-2003 : ported to v2.5 (Dustin McIntire, Sensoria Corp.) -+ * 18-Jun-2008 : ported to NDS32 architecture ( Roy Lee, Andestech Corp.) -+ * 13-Oct-2010 : ported to NDS32 AG102 architecture(Gavin Guo, Andestech Corp.) -+ * -+ * Note: -+ * This driver may change the memory bus clock rate, but will not do any -+ * platform specific access timing changes... for example if you have flash -+ * memory connected to CS0, you will need to register a platform specific -+ * notifier which will adjust the memory access strobes to maintain a -+ * minimum strobe width. -+ * -+ */ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include "pcu.h" -+ -+void __ddr_fsc_lock_start(); -+void __ddr_fsc_lock_end(); -+#define AG102_MIN_FREQ 200000000 -+#define AG102_MAX_FREQ 1000000000 -+#define OSCH3_CLK 33000000 /* 33MHz AG102 */ -+ -+struct ag102_freq_struct { -+ unsigned int khz; /* cpu_clk in khz */ -+ unsigned int sf; /* scaling factor */ -+ unsigned int cr; /* clock ratio */ -+}; -+ -+struct ag102_freq_struct ag102_run_freqs[] = { -+ /* khz sf, cr */ -+ {OSCH3_CLK * 7, 7, 0}, /* CPUA 231MHz */ -+ {OSCH3_CLK * 8, 8, 0}, /* CPUA 264MHz */ -+ {OSCH3_CLK * 9, 9, 0}, -+ {OSCH3_CLK * 10, 10, 0}, -+ {OSCH3_CLK * 11, 11, 0}, -+ {OSCH3_CLK * 12, 12, 0}, -+ {OSCH3_CLK * 13, 13, 0}, -+ {OSCH3_CLK * 14, 14, 0}, -+ {OSCH3_CLK * 15, 15, 0}, -+ {OSCH3_CLK * 16, 16, 0}, -+ /* -+ * {OSCH3_CLK * 17, 17, 0}, -+ * {OSCH3_CLK * 18, 18, 0}, -+ * {OSCH3_CLK * 19, 19, 0}, -+ * {OSCH3_CLK * 20, 20, 0}, -+ * {OSCH3_CLK * 21, 21, 0}, -+ * {OSCH3_CLK * 22, 22, 0}, -+ * {OSCH3_CLK * 23, 23, 0}, -+ * {OSCH3_CLK * 24, 24, 0}, -+ * {OSCH3_CLK * 25, 25, 0}, -+ * {OSCH3_CLK * 26, 26, 0}, -+ * {OSCH3_CLK * 27, 27, 0}, -+ * {OSCH3_CLK * 28, 28, 0}, -+ * {OSCH3_CLK * 29, 29, 0}, -+ * {OSCH3_CLK * 30, 30, 0}, -+ */ -+ {0} /* The last 30 is CPUA 1000MHz */ -+}; -+ -+#define NUM_RUN_FREQS ARRAY_SIZE(ag102_run_freqs) -+static struct cpufreq_frequency_table ag102_run_freq_table[NUM_RUN_FREQS + 1]; -+ -+/* Generic helper function get CPU clocks in kHz */ -+unsigned int ag102_cpufreq_get(unsigned int dummy) -+{ -+ unsigned int main_PLL_M = 1; -+ unsigned int main_PLL_out; -+ unsigned int main_PLL_div; -+ unsigned int ratio; -+ unsigned int main_PLL_N; -+ unsigned int pcs1_param; -+ unsigned int pcs4_param; -+ -+ pcs1_param = PCU_GET_REG(PCS1_ST2); -+ main_PLL_div = PCU_EXTRACT(PCS1_ST2, DIV, pcs1_param); -+ ratio = PCU_EXTRACT(PCS1_ST2, RATIO, pcs1_param); -+ -+ pcs4_param = PCU_GET_REG(PCS4_ST2); -+ main_PLL_N = PCU_EXTRACT(PCS4_ST2, N_FACTOR, pcs4_param); -+ main_PLL_out = (OSCH3_CLK * main_PLL_N / main_PLL_M) >> main_PLL_div; -+ -+ printk("CPU frequency is %d\n", main_PLL_out); -+ return main_PLL_out; -+} -+ -+/* find a valid frequency point */ -+static int ag102_verify_policy(struct cpufreq_policy *policy) -+{ -+ printk("Verified CPU policy: %dKhz min to %dKhz max\n", policy->min, -+ policy->max); -+ return cpufreq_frequency_table_verify(policy, ag102_run_freq_table); -+} -+ -+void wakeup_and_ddr_train(void) -+{ -+ unsigned int csr_reg; -+ unsigned long ddr2_va_base = DDR2C_VA_BASE; -+ /* issue standby */ -+ /*standby(PCU_STBY_WAIT_DONE); */ -+ __asm__ __volatile__("__fcs_stby:"); -+ __asm__ __volatile__("standby wait_done"); -+ /* Fill the inline assembly codes into Cache to avoid SDRAM access before the data training is done */ -+ __asm__ __volatile__("__ddr_fsc_lock_start:\n" -+ "li $p0, %0 \n" -+ "lwi $p1, [$p0 + 0x1f0] \n" -+ "ori $p1, $p1, 0x100 \n" -+ "swi $p1, [$p0 + 0x1f0] ! DLL Reset \n" -+ "msync \n" -+ "isb \n" -+ "1: \n" -+ "lwi $p1, [$p0 + 0x1f0] \n" -+ "andi $p1, $p1, 0x100 \n" -+ "bnez $p1, 1b ! Wait until DLL reset is done\n" -+ "__trigger_dt:\n" -+ "li $p0, %1 \n" -+ "lwi $p1, [$p0] \n" -+ "li $p0, 0x40000000 \n" -+ "or $p1, $p1, $p0 \n" -+ "li $p0, %2 \n" -+ "swi $p1, [$p0] ! Trigger data training\n" -+ "msync \n" -+ "isb \n" -+ "li $p0, %3 \n" -+ "__wait_init_0:\n" -+ "lwi $p1, [$p0 + 0xc] \n" -+ "srli $p1, $p1, 23 \n" -+ "andi $p1, $p1, 0x1 \n" -+ "bnez $p1, __wait_init_0 ! Wait until init bit in CSR == 0\n" -+ "lwi $p1, [$p0 + 0xc] \n" -+ "srli $p1, $p1, 20 \n" -+ "andi $p1, $p1, 0x1 \n" -+ "beqz $p1, __dt_pass ! Monitor data training result\n" -+ "li $p0, 0xff942000 \n" -+ "li $p1, 0x45 \n" -+ "swi $p1, [$p0] ! put 'E' to UART\n" -+ "li $p1, 0x52 \n" -+ "swi $p1, [$p0] ! put 'R' to UART\n" -+ "li $p1, 0x52 \n" -+ "swi $p1, [$p0] ! put 'R' to UART\n" -+ "li $p1, 0x4f \n" -+ "swi $p1, [$p0] ! put 'O' to UART\n" -+ "li $p1, 0x52 \n" -+ "swi $p1, [$p0] ! put 'R' to UART\n" -+ "li $p1, 0xd \n" -+ "swi $p1, [$p0] ! put '\\r' to UART\n" -+ "li $p1, 0xa \n" -+ "swi $p1, [$p0] ! put '\\n' to UART\n" -+ "j __ddr_fsc_lock_end \n" -+ "__dt_pass:\n" -+ "li $p0, 0xff942000 \n" -+ "li $p1, 0x50 \n" -+ "swi $p1, [$p0] ! put 'P' to UART\n" -+ "li $p1, 'A \n" -+ "swi $p1, [$p0] ! put 'A' to UART\n" -+ "li $p1, 0x53 \n" -+ "swi $p1, [$p0] ! put 'S' to UART\n" -+ "li $p1, 0x53 \n" -+ "swi $p1, [$p0] ! put 'S' to UART\n" -+ "li $p1, '\\r \n" -+ "swi $p1, [$p0] ! put '\\r' to UART\n" -+ "li $p1, '\\n \n" -+ "swi $p1, [$p0] ! put '\\n' to UART\n" -+ "__ddr_fsc_lock_end: \n":: -+ "r" -+ (ddr2_va_base), -+ "r" -+ (ddr2_va_base), -+ "r"(ddr2_va_base), "r"(ddr2_va_base)); -+ -+ csr_reg = GET_REG(DDR2C_VA_BASE + 0xc); -+ if (csr_reg & 0x100000) { -+ printk("\n###### Data training error ######\nCSR = 0x%x\n\n", -+ csr_reg); -+ } -+} -+ -+void check_status() -+{ -+ unsigned int reg_value_tmp; -+ -+ /* -+ * CPU will continue if it is waked up -+ * => check status -+ */ -+ reg_value_tmp = PCU_GET_REG(BSM_STATUS); -+ if (PCU_EXTRACT(BSM_STATUS, STS, reg_value_tmp) != PCS_BSM_DONE) { -+ printk("ERROR: BSM status is not expected:0x%x\n", -+ reg_value_tmp); -+ } -+ PCU_SET_REG(BSM_STATUS, 0x0); // write to clear the status -+ -+ /* -+ * Maybe we will need the following code in the future -+ * if (pcs1_used) { -+ * reg_value_tmp = PCU_GET_REG(PCS1_ST1); -+ * if (PCU_EXTRACT(PCS1_ST1, STS, reg_value_tmp) != PCS_STS_DONE) { -+ * printk("ERROR: PCS1 status is not expected:0x%x\n", reg_value_tmp); -+ * printk("DEBUG: PCS1 status 2 is 0x%x\n", PCU_GET_REG(PCS1_ST2)); -+ * } -+ * PCU_SET_REG(PCS1_ST1, 0x0); // write to clear the status -+ * pcs1_used = 0; -+ * } -+ */ -+ -+ /* if (pcs4_used) { */ -+ reg_value_tmp = PCU_GET_REG(PCS4_ST1); -+ if (PCU_EXTRACT(PCS4_ST1, STS, reg_value_tmp) != PCS_STS_DONE) { -+ printk("ERROR: PCS4 status is not expected:0x%x\n", -+ reg_value_tmp); -+ printk("DEBUG: PCS4 status 2 is 0x%x\n", PCU_GET_REG(PCS4_ST2)); -+ } -+ PCU_SET_REG(PCS4_ST1, 0x0); /* write to clear the status */ -+ /* pcs4_used = 0; */ -+ /* } */ -+ -+} -+ -+void start_fcs(unsigned int pll_n_factor, unsigned org_div_param) -+{ -+ unsigned int pll_range; -+ unsigned int pcs4_prmtr; -+ -+ /* -+ * We must keep the frequency between 266~533. -+ * because this is the frequency having been tested. -+ */ -+ if (org_div_param == 0) { -+ if ((pll_n_factor < 7) || (pll_n_factor > 16)) { /* 266~533 */ -+ printk("\npll_n_factor:%d, org_div_param:%d\n", -+ pll_n_factor, org_div_param); -+ printk -+ ("The input is not accepted! Please input the other value\n"); -+ return; -+ } -+ } else { /* div = 1(the divsior is 2), (pll_n_factor*33MHz/2) */ -+ if (pll_n_factor < 16) { /* (533/2~1000/2) */ -+ printk("\npll_n_factor:%d, org_div_param:%d\n", -+ pll_n_factor, org_div_param); -+ printk -+ ("The input is not accepted! Please input the other value\n"); -+ return; -+ } -+ -+ } -+ /* Setup the pll_range, pcu need to know the frequency which we setup */ -+ if (org_div_param == 0) { -+ if (pll_n_factor <= 15) { -+ pll_range = 2; -+ } else -+ pll_range = 3; -+ } else if (org_div_param == 1) { -+ if (pll_n_factor >= 16 && pll_n_factor <= 30) { -+ pll_range = 2; -+ } else -+ pll_range = 3; -+ } -+ -+ printk("\npll_n_factor:%d, org_div_param:%d, pll_range:%d\n", -+ pll_n_factor, org_div_param, pll_range); -+ /* PCS4 */ -+ PCU_SET_REG(PCS4_CFG, 0); /* stop */ -+ pcs4_prmtr = PCU_PREPARE(PCS4_PARA, IE, 1) | PCU_PREPARE(PCS4_PARA, CMD, PCS_CMD_NOP) | PCU_PREPARE(PCS4_PARA, SYNC, 1) | PCU_PREPARE(PCS4_PARA, PWDN, 0) | PCU_PREPARE(PCS4_PARA, RANGE, pll_range) | /* PLL range */ -+ pll_n_factor; /* PLL N factor */ -+ PCU_SET_REG(PCS4_PARA, pcs4_prmtr); -+ -+ /* BSM */ -+ PCU_SET_REG(BSM_CTRL, PCU_PREPARE(BSM_CTRL, IE, 1) | PCU_PREPARE(BSM_CTRL, CMD, PCS_CMD_SCALING | PCS_CMD_DRAM_SF) | PCU_PREPARE(BSM_CTRL, SYNC, 1) | PCU_PREPARE(BSM_CTRL, LINK0, 4) | /* scaling link start */ -+ PCU_PREPARE(BSM_CTRL, LINK1, 0x0)); /* wakeup link start */ -+ wakeup_and_ddr_train(); -+ check_status(); -+} -+ -+void end_fcs(void) -+{ -+ /* Leave this function as a place marker. */ -+} -+ -+#define LPS_PREC 8 -+void calibration() -+{ -+ unsigned long ticks, loopbit, lpj; -+ int lps_precision = LPS_PREC; -+ -+ lpj = (1 << 12); -+ -+ printk(KERN_INFO "Calibrating delay loop... "); -+ while ((lpj <<= 1) != 0) { -+ /* wait for "start of" clock tick */ -+ ticks = jiffies; -+ while (ticks == jiffies) -+ /* nothing */ ; -+ /* Go .. */ -+ ticks = jiffies; -+ __delay(lpj); -+ ticks = jiffies - ticks; -+ if (ticks) -+ break; -+ } -+ -+ /* -+ * Do a binary approximation to get lpj set to -+ * equal one clock (up to lps_precision bits) -+ */ -+ lpj >>= 1; -+ loopbit = lpj; -+ while (lps_precision-- && (loopbit >>= 1)) { -+ lpj |= loopbit; -+ ticks = jiffies; -+ while (ticks == jiffies) -+ /* nothing */ ; -+ ticks = jiffies; -+ __delay(lpj); -+ if (jiffies != ticks) /* longer than 1 tick */ -+ lpj &= ~loopbit; -+ } -+ -+ printk(KERN_CONT "%lu.%02lu BogoMIPS modified(lpj=%lu)\n", -+ lpj / (500000 / HZ), (lpj / (5000 / HZ)) % 100, lpj); -+} -+ -+static int ag102_speedstep(int idx) -+{ -+ unsigned int j; -+ char ch = 'a'; -+ unsigned int sf, cr; -+ unsigned long flags = 0; -+ unsigned long org_div_param; -+ void (*do_fcs) (unsigned int efsf, unsigned int edivhbaclk); -+ int i; -+ int line_size = CACHE_LINE_SIZE(ICACHE); -+ unsigned long start = -+ ((unsigned long)__ddr_fsc_lock_start) & ~(line_size - 1); -+ unsigned long end = -+ (((unsigned long)__ddr_fsc_lock_end) + line_size) & ~(line_size - -+ 1); -+ -+ printk("&__ddr_fsc_lock_start(): 0x%08lx, aligned to: 0x%08lx\n", -+ (unsigned long)__ddr_fsc_lock_start, start); -+ printk("&__ddr_fsc_lock_end(): 0x%08lx, aligned to: 0x%08lx\n", -+ (unsigned long)__ddr_fsc_lock_end, end); -+ -+ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_FILLCK":: -+ "r" (i):"memory"); -+ -+ do_fcs = start_fcs; -+ org_div_param = (PCU_GET_REG(PCS1_ST2) >> 4) & 0x3; -+ sf = ag102_run_freqs[idx].sf; -+ if (org_div_param == 1) -+ sf *= 2; -+#if 0 -+ calibration(); -+ printk("pcu read value,before frequency scaling:"); -+ ag102_cpufreq_get(0); -+#endif -+ local_irq_save(flags); -+ do_fcs(sf, org_div_param); -+ local_irq_restore(flags); -+#if 0 -+ printk("\npcu read value,after frequency scaling:"); -+ ag102_cpufreq_get(0); -+#endif -+ -+ for (i = start; i <= end; i += CACHE_LINE_SIZE(ICACHE)) -+ __asm__ volatile ("\n\tcctl %0, L1I_VA_ULCK"::"r" (i):"memory"); -+ -+ return 1; -+} -+ -+static int ag102_set_target(struct cpufreq_policy *policy, -+ unsigned int target_freq, unsigned int relation) -+{ -+ unsigned int idx, i, j; -+ char ch = 'a'; -+ struct cpufreq_frequency_table *ag102_freqs_table; -+ struct ag102_freq_struct *ag102_freq_settings; -+ struct cpufreq_freqs freqs; -+ -+ ag102_freq_settings = ag102_run_freqs; -+ ag102_freqs_table = ag102_run_freq_table; -+ -+ if (target_freq > AG102_MAX_FREQ || target_freq < AG102_MIN_FREQ) { -+ printk -+ ("\nThe frequency you input is illegal!!Please enter the frequency between %d ~ %d\n", -+ AG102_MIN_FREQ, AG102_MAX_FREQ); -+ return -EINVAL; -+ } -+ -+ /* Lookup the next frequency */ -+ if (cpufreq_frequency_table_target -+ (policy, ag102_freqs_table, target_freq, relation, &idx)) -+ return -EINVAL; -+ -+ freqs.old = policy->cur; -+ freqs.new = ag102_freq_settings[idx].khz; -+ freqs.cpu = policy->cpu; -+ -+ /* -+ * Tell everyone what we're about to do... -+ * you should add a notify client with any platform specific -+ * Vcc changing capability -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_PRECHANGE); -+ -+ if (freqs.new != freqs.old) { -+ -+ if (!ag102_speedstep(idx)) -+ return -ENODEV; -+ } -+ -+ /* -+ * Tell everyone what we've just done... -+ * you should add a notify client with any platform specific -+ * SDRAM refresh timer adjustments -+ */ -+ cpufreq_notify_transition(&freqs, CPUFREQ_POSTCHANGE); -+#if 0 -+ printk("After CPUFREQ_POSTCHANGE, scaling:\n"); -+ calibration(); -+ printk("Speed test..."); -+ for (i = 0; i < 26; i++) { -+ for (j = 0; j < 500000000; j++) ; -+ printk("%c", ch); -+ ch += 1; -+ } -+ printk("\n"); -+#endif -+ return 0; -+} -+ -+static int ag102_cpufreq_init(struct cpufreq_policy *policy) -+{ -+ int i; -+ /* set default policy and cpuinfo */ -+ policy->governor = CPUFREQ_DEFAULT_GOVERNOR; -+ policy->policy = CPUFREQ_POLICY_PERFORMANCE; -+ policy->cpuinfo.max_freq = AG102_MAX_FREQ; -+ policy->cpuinfo.min_freq = AG102_MIN_FREQ; -+ policy->cpuinfo.transition_latency = 1000; /* FIXME: 1 ms, assumed */ -+ policy->cur = ag102_cpufreq_get(0); /* current freq */ -+ policy->min = AG102_MIN_FREQ; -+ policy->max = AG102_MAX_FREQ; -+ -+ /* Generate the run cpufreq_frequency_table struct */ -+ for (i = 0; i < NUM_RUN_FREQS; i++) { -+ -+ ag102_run_freq_table[i].frequency = ag102_run_freqs[i].khz; -+ ag102_run_freq_table[i].index = i; -+ } -+ -+ ag102_run_freq_table[i].frequency = CPUFREQ_TABLE_END; -+ -+ printk("CPU frequency change support initialized\n"); -+ -+ return 0; -+} -+ -+static struct cpufreq_driver ag102_cpufreq_driver = { -+ -+ .verify = ag102_verify_policy, -+ .target = ag102_set_target, -+ .init = ag102_cpufreq_init, -+ .get = ag102_cpufreq_get, -+ .name = "AG102", -+}; -+ -+static int __init ag102_cpu_init(void) -+{ -+ return cpufreq_register_driver(&ag102_cpufreq_driver); -+} -+ -+static void __exit ag102_cpu_exit(void) -+{ -+ cpufreq_unregister_driver(&ag102_cpufreq_driver); -+} -+ -+MODULE_AUTHOR("Andes Technology Corporation"); -+MODULE_DESCRIPTION("CPU frequency changing driver for the AG102 architecture"); -+MODULE_LICENSE("GPL"); -+module_init(ag102_cpu_init); -+module_exit(ag102_cpu_exit); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/gmac.h linux-3.4.113/arch/nds32/platforms/ag102/gmac.h ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/gmac.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/gmac.h 2016-12-01 20:59:24.376613676 +0100 -@@ -0,0 +1,354 @@ -+#ifdef CONFIG_PLAT_AG102 -+#include -+#else -+#include -+#endif -+ -+#ifndef __GMAC_H -+#define __GMAC_H -+ -+// ====================================================== -+// GMAC register definition -+// ====================================================== -+// GMAC register -+// -+//#define CPE_GMAC_BASE 0xFF90B000 //VA Base -+#define CPE_DDR2_MEM_BASE 0x00000000 -+ -+#define BIT_MASK(bit_h, bit_l) ((((UINT32)0x1<<(1+bit_h-bit_l))-(UINT32)0x1)< -+#include -+#include -+ -+#include -+ -+#define LPC_REG_SCR 0x10 -+#define LPC_REG_SIR 0x14 -+#define LPC_REG_SIMR 0x18 -+ -+/* -+ * Level trigger IRQ chip methods -+ */ -+ -+static void lpc_level_unmask_irq(unsigned int irq) -+{ -+ unsigned int val; -+// *(volatile unsigned int *) (LPC_REG_BASE + LPC_REG_SIR) = -+// 1 << (irq - PLATFORM_LPC_IRQ_BASE); -+ val = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR); -+ val &= ~(1 << (irq - PLATFORM_LPC_IRQ_BASE)); -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = val; -+} -+ -+static void lpc_level_mask_irq(unsigned int irq) -+{ -+ unsigned int val; -+ val = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR); -+ val |= 1 << (irq - PLATFORM_LPC_IRQ_BASE); -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = val; -+} -+ -+static void lpc_level_ack_irq(unsigned int irq) -+{ -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR) = -+ 1 << (irq - PLATFORM_LPC_IRQ_BASE); -+} -+ -+static struct irq_chip lpc_simple_chip = { -+ .ack = lpc_level_ack_irq, -+ .mask = lpc_level_mask_irq, -+ .unmask = lpc_level_unmask_irq, -+}; -+ -+void lpc_irq_rounter(unsigned int irq, struct irq_desc *desc) -+{ -+ unsigned int lpc_status; -+ unsigned int lpc_mask; -+ unsigned int lpc_irq; -+ int i; -+ struct irq_desc *lpc_desc; -+ -+ desc->chip->mask(irq); -+ desc->chip->ack(irq); -+ -+ lpc_status = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR); -+ lpc_mask = *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR); -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = 0xffffffff; -+ for (i = 0; i < PLATFORM_LPC_IRQ_TOTALCOUNT; i++) { -+ if (!(~lpc_mask & (1 << i) & lpc_status)) -+ continue; -+ lpc_irq = PLATFORM_LPC_IRQ_BASE + i; -+ lpc_desc = irq_desc + lpc_irq; -+ lpc_desc->handle_irq(lpc_irq, lpc_desc); -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIR) = -+ 1 << i; -+ } -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SIMR) = lpc_mask; -+ -+ desc->chip->unmask(irq); -+} -+ -+int __init lpc_init_irq(void) -+{ -+ int i; -+ -+ *(volatile unsigned int *)(LPC_REG_VA_BASE + LPC_REG_SCR) = 0x1f3; -+ /* Register all IRQ */ -+ for (i = PLATFORM_LPC_IRQ_BASE; -+ i < PLATFORM_LPC_IRQ_BASE + PLATFORM_LPC_IRQ_TOTALCOUNT; i++) { -+ // level trigger -+ set_irq_chip(i, &lpc_simple_chip); -+ set_irq_handler(i, handle_simple_irq); -+ -+ } -+ set_irq_chained_handler(LPC_IRQ, lpc_irq_rounter); -+ -+ return 0; -+} -+ -+device_initcall(lpc_init_irq); -+ -+#define ITE_ADDR 0x2e -+#define ITE_DATA 0x2f -+void outlpc(unsigned int addr, unsigned int data) -+{ -+ *(volatile unsigned int *)(LPC_IO_VA_BASE + 4 * addr) = data; -+} -+ -+unsigned int inlpc(unsigned int addr) -+{ -+ return *(volatile unsigned int *)(LPC_IO_VA_BASE + 4 * addr); -+} -+ -+int __init ite8717_init(void) -+{ -+ unsigned char data1, data2; -+ unsigned int count; -+ /* enter configure mode */ -+ outlpc(ITE_ADDR, 0x87); -+ outlpc(ITE_ADDR, 0x01); -+ outlpc(ITE_ADDR, 0x55); -+ outlpc(ITE_ADDR, 0x55); -+ /* check chip */ -+ outlpc(ITE_ADDR, 0x20); -+ data1 = inlpc(ITE_DATA); -+ outlpc(ITE_ADDR, 0x21); -+ data2 = inlpc(ITE_DATA); -+ if ((data1 != 0x87) && (data2 != 0x17)) -+ goto not_found; -+ /* earlyio program */ -+ outlpc(ITE_ADDR, 0x07); // LDN=0 -> FDC -+ outlpc(ITE_DATA, 0x00); -+ outlpc(ITE_ADDR, 0x30); // Enable FDC -+ outlpc(ITE_DATA, 0x01); -+ outlpc(ITE_ADDR, 0xf1); // Set (Index 0F1h) = 90h -+ outlpc(ITE_DATA, 0x80); -+ -+ outlpc(0x64, 0xaa); // Send KBC self-test command -+ count = 0; -+ do { -+ if (count++ > 0x10000) -+ break; -+ data1 = ~inlpc(0x64); -+ } while (data1 & 0x01); -+ data2 = inlpc(0x60); -+ outlpc(0x64, 0xcb); // Set PS2 mode -+ count = 0; -+ do { -+ if (count++ > 0x10000) -+ break; -+ data1 = inlpc(0x64); -+ } while (data1 & 0x02); -+ outlpc(0x60, 0x01); -+ count = 0; -+ do { -+ if (count++ > 0x10000) -+ break; -+ data1 = inlpc(0x64); -+ } while (data1 & 0x02); -+ outlpc(0x64, 0x60); // 60h = write 8042 command byte -+ count = 0; -+ do { -+ if (count++ > 0x10000) -+ break; -+ data1 = inlpc(0x64); -+ } while (data1 & 0x02); -+ outlpc(0x60, 0x45); // AT interface, keyboard enabled, system flag -+ count = 0; -+ do { -+ if (count++ > 0x10000) -+ break; -+ data1 = inlpc(0x64); -+ } while (data1 & 0x02); -+ outlpc(0x64, 0xae); -+ count = 0; -+ do { -+ if (count++ > 0x10000) -+ break; -+ data1 = ~inlpc(0x64); -+ } while (data1 & 0x01); -+ outlpc(ITE_ADDR, 0x23); -+ outlpc(ITE_DATA, 0x00); -+ -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x04); -+ outlpc(ITE_ADDR, 0xf0); -+ data1 = inlpc(ITE_DATA); -+ data1 &= 0x18; -+ data1 |= 0x0; -+ outlpc(ITE_DATA, data1); -+ outlpc(ITE_ADDR, 0xf2); -+ data1 = inlpc(ITE_DATA); -+ data1 &= 0x2e; -+ data1 |= 0xa; -+ outlpc(ITE_DATA, data1); -+ outlpc(ITE_ADDR, 0xf4); -+ data1 = inlpc(ITE_DATA); -+ data1 &= 0xaf; -+ data1 |= 0x80; -+ outlpc(ITE_DATA, data1); -+ outlpc(ITE_ADDR, 0xf5); -+ data1 = inlpc(ITE_DATA); -+ data1 &= 0x3f; -+ data1 |= 0x0; -+ outlpc(ITE_DATA, data1); -+ /* initialize all device */ -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x04); -+ outlpc(ITE_ADDR, 0x30); -+ outlpc(ITE_DATA, 0x01); -+#if 1 -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x05); -+ outlpc(ITE_ADDR, 0xf0); -+ outlpc(ITE_DATA, 0x4e); -+ outlpc(ITE_ADDR, 0x71); -+ outlpc(ITE_DATA, 0x01); -+#endif -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x06); -+ outlpc(ITE_ADDR, 0x30); -+ outlpc(ITE_DATA, 0x01); -+#if 1 -+ outlpc(ITE_ADDR, 0xf0); -+ outlpc(ITE_DATA, 0x01); -+ outlpc(ITE_ADDR, 0x71); -+ outlpc(ITE_DATA, 0x01); -+#endif -+ -+ /* exit configure mode */ -+ outlpc(ITE_ADDR, 0x02); -+ outlpc(ITE_DATA, 0x02); -+ return 0; -+not_found: -+ printk("ITE8717 not found\n"); -+ return -1; -+} -+ -+subsys_initcall(ite8717_init); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/Makefile linux-3.4.113/arch/nds32/platforms/ag102/Makefile ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/Makefile 2016-12-01 20:59:24.376613676 +0100 -@@ -0,0 +1,5 @@ -+obj-y += devices.o ahbclkcal.o -+obj-$(CONFIG_LPC) += lpc.o -+obj-$(CONFIG_PM) += pm.o sleep.o -+obj-$(CONFIG_AG102_CPU_FREQ_FCS) += cpu-fcs.o -+obj-$(CONFIG_AG102_CPU_FREQ_SCALING_MODE) += freq-scaling.o -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/pcu.h linux-3.4.113/arch/nds32/platforms/ag102/pcu.h ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/pcu.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/pcu.h 2016-12-01 20:59:24.376613676 +0100 -@@ -0,0 +1,1887 @@ -+#ifndef __PCU_H -+#define __PCU_H -+#include -+#define CPE_PCU_BASE PCU_VA_BASE -+//Data type -+typedef enum Bool { -+ FALSE, -+ TRUE -+} BOOL; -+ -+typedef enum { -+ SUCCESS=0, -+ FAIL -+} STATUS; -+ -+typedef unsigned char UINT8; -+typedef char INT8; -+typedef unsigned short UINT16; -+typedef short INT16; -+typedef unsigned int UINT32; -+typedef int INT32; -+typedef unsigned long long UINT64; -+typedef long long INT64; -+ -+//Registion IO operation macro -+#define REG32(a) (*(volatile UINT32 *)(a)) -+#define REG16(a) (*(volatile UINT16 *)(a)) -+#define REG8(a) (*(volatile UINT8 *)(a)) -+ -+#define inb(a) REG8(a) -+#define inhw(a) REG16(a) -+#define inw(a) REG32(a) -+ -+#define outb(a, v) (REG8(a) = (UINT8)(v)) -+#define outhw(a, v) (REG16(a) = (UINT16)(v)) -+#define outw(a, v) (REG32(a) = (UINT32)(v)) -+ -+ -+// Register bit operation macro -+#define ANDES_BIT_MASK(bit_h, bit_l) ((((UINT32)0x1<<(1+bit_h-bit_l))-(UINT32)0x1)<> (offset)) -+ -+#define TEST_FIELD(addr, mask) (inw(addr)&(mask)) -+ -+#define SET_REG(addr, value) do { outw(addr, value); } while (0) -+#define GET_REG(addr) (inw(addr)) -+ -+#define CHECK_FIELD(value, mask) ( (value)&(mask) ) -+#define EXTRACT_FIELD(value, mask, offset) ( ((value)&(mask))>>(offset) ) -+#define PREPARE_FIELD(value, mask, offset) ( ((value)<<(offset))&(mask) ) -+ -+ -+// Variable bit operation macro -+#define VAR_TEST_BIT(var, sig) ((var)&(sig)) -+#define VAR_SET_BIT(var, sig) ((var) = (var)|(sig)) -+#define VAR_CLR_BIT(var, sig) ((var) = (var)&(~(sig))) -+// ============================ -+// PCU register definition -+// ============================ -+#define PCU_REG_VER (CPE_PCU_BASE+0x000) //version -+#define PCU_REG_SPINFO (CPE_PCU_BASE+0x004) //scartch pad information -+#define PCU_REG_SOCID (CPE_PCU_BASE+0x010) //SoC ID -+#define PCU_REG_AHB_CFG (CPE_PCU_BASE+0x014) //AHB device configuration -+#define PCU_REG_APB_CFG (CPE_PCU_BASE+0x018) //APB device configuration -+#define PCU_REG_DCSR0 (CPE_PCU_BASE+0x020) //driving capability and slew rate control 0 -+#define PCU_REG_DCSR1 (CPE_PCU_BASE+0x024) //driving capability and slew rate control 1 -+#define PCU_REG_DCSR2 (CPE_PCU_BASE+0x028) //driving capability and slew rate control 2 -+#define PCU_REG_MFPS0 (CPE_PCU_BASE+0x030) //multi-function port setting 0 -+#define PCU_REG_MFPS1 (CPE_PCU_BASE+0x034) //multi-function port setting 1 -+#define PCU_REG_DMA_SEL (CPE_PCU_BASE+0x038) //dma engin selection -+#define PCU_REG_OSC_CTRL (CPE_PCU_BASE+0x040) //OSC control register -+#define PCU_REG_PWM_DIV (CPE_PCU_BASE+0x044) //PWM clock divider value -+#define PCU_REG_MISC (CPE_PCU_BASE+0x048) //misc register -+#define PCU_REG_BSM_CTRL (CPE_PCU_BASE+0x080) //BSM control register -+#define PCU_REG_BSM_STATUS (CPE_PCU_BASE+0x084) //BSM status -+#define PCU_REG_WAKEUP_SEN (CPE_PCU_BASE+0x088) //wakeup event signal sensitivity -+#define PCU_REG_WAKEUP_STATUS (CPE_PCU_BASE+0x08c) //wakeup event status -+#define PCU_REG_RESET_TIMER (CPE_PCU_BASE+0x090) //reset timer register -+#define PCU_REG_INTR (CPE_PCU_BASE+0x094) //interrup register -+#define PCU_REG_PCS1_CFG (CPE_PCU_BASE+0x0a0) -+#define PCU_REG_PCS1_PARA (CPE_PCU_BASE+0x0a4) -+#define PCU_REG_PCS1_ST1 (CPE_PCU_BASE+0x0a8) -+#define PCU_REG_PCS1_ST2 (CPE_PCU_BASE+0x0ac) -+#define PCU_REG_PCS1_PDD (CPE_PCU_BASE+0x0b0) -+#define PCU_REG_PCS2_CFG (CPE_PCU_BASE+0x0c0) -+#define PCU_REG_PCS2_PARA (CPE_PCU_BASE+0x0c4) -+#define PCU_REG_PCS2_ST1 (CPE_PCU_BASE+0x0c8) -+#define PCU_REG_PCS2_ST2 (CPE_PCU_BASE+0x0cc) -+#define PCU_REG_PCS2_PDD (CPE_PCU_BASE+0x0d0) -+#define PCU_REG_PCS3_CFG (CPE_PCU_BASE+0x0e0) -+#define PCU_REG_PCS3_PARA (CPE_PCU_BASE+0x0e4) -+#define PCU_REG_PCS3_ST1 (CPE_PCU_BASE+0x0e8) -+#define PCU_REG_PCS3_ST2 (CPE_PCU_BASE+0x0ec) -+#define PCU_REG_PCS3_PDD (CPE_PCU_BASE+0x0f0) -+#define PCU_REG_PCS4_CFG (CPE_PCU_BASE+0x100) -+#define PCU_REG_PCS4_PARA (CPE_PCU_BASE+0x104) -+#define PCU_REG_PCS4_ST1 (CPE_PCU_BASE+0x108) -+#define PCU_REG_PCS4_ST2 (CPE_PCU_BASE+0x10c) -+#define PCU_REG_PCS4_PDD (CPE_PCU_BASE+0x110) -+#define PCU_REG_PCS5_CFG (CPE_PCU_BASE+0x120) -+#define PCU_REG_PCS5_PARA (CPE_PCU_BASE+0x124) -+#define PCU_REG_PCS5_ST1 (CPE_PCU_BASE+0x128) -+#define PCU_REG_PCS5_ST2 (CPE_PCU_BASE+0x12c) -+#define PCU_REG_PCS5_PDD (CPE_PCU_BASE+0x130) -+#define PCU_REG_PCS6_CFG (CPE_PCU_BASE+0x140) -+#define PCU_REG_PCS6_PARA (CPE_PCU_BASE+0x144) -+#define PCU_REG_PCS6_ST1 (CPE_PCU_BASE+0x148) -+#define PCU_REG_PCS6_ST2 (CPE_PCU_BASE+0x14c) -+#define PCU_REG_PCS6_PDD (CPE_PCU_BASE+0x150) -+#define PCU_REG_PCS7_CFG (CPE_PCU_BASE+0x160) -+#define PCU_REG_PCS7_PARA (CPE_PCU_BASE+0x164) -+#define PCU_REG_PCS7_ST1 (CPE_PCU_BASE+0x168) -+#define PCU_REG_PCS7_ST2 (CPE_PCU_BASE+0x16c) -+#define PCU_REG_PCS7_PDD (CPE_PCU_BASE+0x170) -+#define PCU_REG_PCS8_CFG (CPE_PCU_BASE+0x180) -+#define PCU_REG_PCS8_PARA (CPE_PCU_BASE+0x184) -+#define PCU_REG_PCS8_ST1 (CPE_PCU_BASE+0x188) -+#define PCU_REG_PCS8_ST2 (CPE_PCU_BASE+0x18c) -+#define PCU_REG_PCS8_PDD (CPE_PCU_BASE+0x190) -+#define PCU_REG_PCS9_CFG (CPE_PCU_BASE+0x1a0) -+#define PCU_REG_PCS9_PARA (CPE_PCU_BASE+0x1a4) -+#define PCU_REG_PCS9_ST1 (CPE_PCU_BASE+0x1a8) -+#define PCU_REG_PCS9_ST2 (CPE_PCU_BASE+0x1ac) -+#define PCU_REG_PCS9_PDD (CPE_PCU_BASE+0x1b0) -+ -+#define PCU_SCRATCH_OFFSET_SHIFT (8) -+#define PCU_SCRATCH_SIZE_SHIFT (2) // in byte, 2 means (1<<2) = 4 bytes -+#define PCU_REG_SCRATCH_MEM (CPE_PCU_BASE+ (PCU_SPINFO_OFFSET_DEFAULT< -+ * -+ * This program is free software; you can redistribute it and/or -+ * modify it under the terms of the GNU General Public License. -+ * -+ * Abstract: -+ * -+ * This program is for AG102 power management routines. -+ * -+ * Revision History: -+ * -+ * Jul.19.2010 Initial code by Gavin. -+ */ -+#include -+#include -+#include -+#include -+#include -+/* -+ * the following include file is for testing device node -+ */ -+#include -+#include -+#include -+/*************************/ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include "pcu.h" -+#include "gmac.h" -+ -+#ifdef CONFIG_PLAT_AG102 -+#include -+#endif -+ -+#define ANDES_PCU_STRING "andes_pcu" -+static int andes_pcu_major; -+static struct class *andes_pcu_class; -+extern void ag102_cpu_sleep(void); -+extern void ag102_cpu_resume(void); -+extern void ag102_cpu_resume2(void); -+extern void __SELF_REFRESH_LOCK_START(); -+extern void __SELF_REFRESH_LOCK_END(); -+extern void ftpci_postinit(void /**sysdata*/ ); -+UINT32 mac_dah, mac_dal; -+ -+// ADD by river 2010.12.07 for WOL -+ -+UINT32 eth_phy_reg_read(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg, -+ UINT32 * phy_data) -+{ -+ UINT32 cycthr = GMAC_GET_FIELD(PHYCR, MDC_CYCTHR); -+ UINT32 wdata; -+ UINT32 rdata; -+ //TIMER_P timer; -+ -+ printk(">>>>> GMAC : Calling eth_phy_reg_read()...\n"); -+ -+ wdata = GMAC_PREPARE(PHYCR, MIIRD, 0x1) | -+ GMAC_PREPARE(PHYCR, PHYAD, phy_addr) | -+ GMAC_PREPARE(PHYCR, REGAD, phy_reg) | cycthr; -+ -+ printk(">>>>> GMAC : wdata = [0x%08x]\n", wdata); -+ -+ GMAC_SET_REG(PHYCR, wdata); -+ -+ // wait phy data read -+ //TIMER_INIT(timer, 10000); // trigger timer & wait until finish of data read -+ //while ( (!TIMER_IS_TIMEOUT(timer)) && (GMAC_GET_FIELD(PHYCR, MIIRD))) { -+ // TIMER_TICK(timer); -+ //} -+ -+ while (GMAC_GET_FIELD(PHYCR, MIIRD)) { -+ mdelay(50); -+ } -+ -+ if (GMAC_GET_FIELD(PHYCR, MIIRD)) { -+ printk("ERR: GPHY read reg[%x] timeout!\n", phy_reg); -+ return 1; -+ } else { -+ rdata = GMAC_GET_FIELD(PHYDATA, MIIRDATA); -+ *phy_data = rdata; -+ printk("GPHY read [%x] \n", rdata); -+ return 0; -+ } -+} -+ -+UINT32 eth_phy_reg_write(UINT32 phy_addr, UINT32 phy_page, UINT32 phy_reg, -+ UINT32 phy_data) -+{ -+ UINT32 wdata; -+ //TIMER_P timer; -+ -+ printk(">>>>> GMAC : Calling eth_phy_reg_write()...\n"); -+ -+ GMAC_SET_FIELD(PHYDATA, MIIWDATA, phy_data); -+ wdata = GMAC_PREPARE(PHYCR, MIIWR, 0x1) | GMAC_PREPARE(PHYCR, PHYAD, phy_addr) | GMAC_PREPARE(PHYCR, REGAD, phy_reg) | 0x34; //cycthr; -+ GMAC_SET_REG(PHYCR, wdata); -+ -+ // wait phy data write -+ //TIMER_INIT(timer, 10000); // trigger timer & wait until finish of data write -+ //while ( (!TIMER_IS_TIMEOUT(timer)) && (GMAC_GET_FIELD(PHYCR, MIIWR))) { -+ // TIMER_TICK(timer); -+ //} -+ -+ while (GMAC_GET_FIELD(PHYCR, MIIWR)) { -+ mdelay(50); -+ } -+ -+ if (GMAC_GET_FIELD(PHYCR, MIIWR)) { -+ printk("ERR: GPHY write reg[%x] = %x timeout!\n", phy_reg, -+ phy_data); -+ return 1; -+ } else { -+ return 0; -+ } -+} -+ -+INT32 eth_phy_detect(UINT32 * phy_addr, UINT32 * phy_id) -+{ -+ UINT32 i, find, data1, data2; -+ -+ printk(">>>>> GMAC : Calling eth_phy_detect()...\n"); -+ -+ for (i = 0, find = 0; i <= 0x1f; i++) { -+ eth_phy_reg_read(i, 0, 2, &data1); -+ if ((data1 != 0) && (data1 != 0xffff)) { -+ find = 1; -+ break; -+ } -+ } -+ -+ if (find == 0) { -+ printk("Err: no valid phy found!\n"); -+ *phy_id = 0; -+ return (-1); -+ } -+ -+ eth_phy_reg_read(i, 0, 2, &data1); -+ eth_phy_reg_read(i, 0, 3, &data2); -+ *phy_id = (data1 << 16) | (data2 & 0xffff); -+ *phy_addr = i; -+ printk("Info: phy id = 0x%08x!\n", *phy_id); -+ return 0; -+} -+ -+void eth_phy_init(UINT32 phy_addr) -+{ -+ UINT32 data, i; -+ //TIMER_P timer; -+ //phy_addr = DVC_PHY_ADDR; -+ -+ printk(">>>>> GMAC : Calling eth_phy_init()...\n"); -+ // GPHY SW reset -+ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data); -+ data |= -+ DVC_PHY_REG_CTL_SW_RST | DVC_PHY_REG_CTL_AN_EN | -+ DVC_PHY_REG_CTL_AN_RST; -+ eth_phy_reg_write(phy_addr, 0, DVC_PHY_REG_CTL, data); -+ for (i = 0; i < 10000; i++) { // must delay enough for phy to get ready -+ //eth_mdelay(2000); -+ mdelay(2); -+ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data); -+ if ((data & 0x8000) == 0) -+ break; -+ } -+ if ((data & 0x8000) != 0) { -+ printk("Err: phy sw reset timeout!!!\n"); -+ } -+ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_CTL, &data); -+ printk("phy control = 0x%x\n", data); -+ eth_phy_reg_read(phy_addr, 0, DVC_PHY_REG_STS, &data); -+ printk("phy status = 0x%x\n", data); -+ -+ return; -+} -+ -+// initialize MAC setting -+void eth_mac_init(ETH_PHY_STAT * phy_stat) -+{ -+ UINT32 i, wdata, rdata; -+ UINT32 duplex, speed, gmac; -+ //UINT32 mac_dah, mac_dal; -+ printk(">>>>> GMAC : Calling eth_mac_init()...\n"); -+ -+ wdata = GMAC_PREPARE(MACCR, SW_RST, 0x1); -+ GMAC_SET_REG(MACCR, wdata); -+ for (i = 0; i < 1000; i++) { // must delay enough for phy to get ready -+ //eth_mdelay(8000); // delay should be enough -+ mdelay(8); -+ rdata = GMAC_GET_REG(FEAR); -+ if ((rdata >> 31) == 0) -+ break; -+ } -+ if ((rdata >> 31) != 0) { -+ printk("Err: mac sw reset timeout!!!\n"); -+ } -+ if (phy_stat->speed == 2) { //giga -+ gmac = 0x1; -+ speed = 0x1; -+ } else if (phy_stat->speed == 1) { //100 Mbps -+ gmac = 0x0; -+ speed = 0x1; -+ } else { //10 Mbps -+ gmac = 0x0; -+ speed = 0x0; -+ } -+ duplex = phy_stat->duplex; -+ GMAC_SET_REG(ISR, 0xffff); // Interrupt Status, write 1 to clear -+ GMAC_SET_REG(IME, 0xffff); // Interrupt Enable, enabling all interrupts -+ GMAC_SET_REG(MAC_MADR, mac_dah); -+ GMAC_SET_REG(MAC_LADR, mac_dal); -+ rdata = GMAC_GET_REG(FEAR); -+ GMAC_SET_FIELD(TPAFCR, TFIFO_SIZE, -+ GMAC_EXTRACT(FEAR, TFIFO_RSIZE, rdata)); -+ GMAC_SET_FIELD(TPAFCR, RFIFO_SIZE, -+ GMAC_EXTRACT(FEAR, RFIFO_RSIZE, rdata)); -+ -+ wdata = GMAC_PREPARE(MACCR, RX_MULTIPKT_EN, 0x1) | -+ GMAC_PREPARE(MACCR, BROADPKT_EN, 0x1) | -+ GMAC_PREPARE(MACCR, RX_ALLADR, 0x1) | -+ GMAC_PREPARE(MACCR, CRC_APD, 0x1) | -+ GMAC_PREPARE(MACCR, FULLDUP, duplex) | -+ GMAC_PREPARE(MACCR, RX_RUNT, 0x1) | -+ GMAC_PREPARE(MACCR, SPEED, speed) | -+ GMAC_PREPARE(MACCR, GMAC_MODE, gmac) | -+ GMAC_PREPARE(MACCR, RXMAC_EN, 0x1) | -+ GMAC_PREPARE(MACCR, TXMAC_EN, 0x1) | -+ GMAC_PREPARE(MACCR, RXDMA_EN, 0x1) | -+ GMAC_PREPARE(MACCR, TXDMA_EN, 0x1); -+ GMAC_SET_REG(MACCR, wdata); -+ -+#ifdef AHBC_NO_REMAP -+ GMAC_SET_REG(NPTXR_BADR, FTGMAC100_TXR_BASE | 0x40000000); -+ GMAC_SET_REG(RXR_BADR, FTGMAC100_RXR_BASE | 0x40000000); -+#else -+ GMAC_SET_REG(NPTXR_BADR, FTGMAC100_TXR_BASE); -+ GMAC_SET_REG(RXR_BADR, FTGMAC100_RXR_BASE); -+#endif -+ return; -+} -+ -+UINT32 eth_phy_stat(UINT32 phy_addr, ETH_PHY_STAT * phy_stat) -+{ -+ -+ phy_stat->speed = 0x1; -+ phy_stat->duplex = 0x1; -+ -+ return 0; -+} -+ -+void gmac_set_wol() -+{ -+ UINT32 wdata; -+ -+ // Set Rx Wake-up Frame -+ // write 1 clear register before enable power saving mode -+ GMAC_SET_REG(WOLSR, 0xffffffff); // clear wol status -+ -+ // set wakeup_sel and power saving mode enable -+ wdata = GMAC_PREPARE(WOLCR, MAGICPKT_EN, 0x1) | -+ GMAC_PREPARE(WOLCR, PWRSAV, 0x1); -+ -+ GMAC_SET_REG(WOLCR, wdata); -+ -+ return; -+} -+ -+// End ADD by river 2010.12.07 for WOL -+ -+//////////////////////////////// LPC wake up /////////////////////////////////////////////////// -+#define CPE_LPCIO_BASE LPC_IO_VA_BASE //VA Base -+#define CPE_LPCREG_BASE LPC_REG_VA_BASE //VA Base -+#define CPE_IC_BASE AMIC_VA_BASE -+ -+#define ITE_ADDR 0x2e -+#define ITE_DATA 0x2f -+ -+#define KBC_CMD 0x64 -+#define KBC_STATUS KBC_CMD -+#define KBC_DATA 0x60 -+ -+#define BIT_OBF 0x01 -+#define BIT_IBF 0x02 -+ -+#define LPC_REG_SCR 0x10 -+#define LPC_REG_SIR 0x14 -+#define LPC_REG_SIMR 0x18 -+ -+#define SIRQ_KB 1 -+#define SIRQ_MS 12 -+ -+//#define outlpc(addr, data) outb(data, CPE_LPCIO_BASE + 4 * addr) -+//#define inlpc(addr) inb(CPE_LPCIO_BASE + 4 * addr) -+#define inlpc(addr) REG32(CPE_LPCIO_BASE + 4 * addr) -+ -+#define IRQ_LPC 29 -+#define LEVEL 0 -+#define H_ACTIVE 0 -+#define L_ACTIVE 1 -+#define IRQ_MASK 0x80 -+#define IRQ_MODE 0x20 -+#define IRQ_LEVEL 0x24 -+ -+UINT32 IRQSources = 0; //define the current irq source for debug -+ -+static inline void outlpc(unsigned long addr, unsigned long data) -+{ -+ REG32(CPE_LPCIO_BASE + 4 * addr) = data; -+} -+ -+static void kbc_cmd(UINT8 cmd) -+{ -+ int loop_limit = 1000; -+ int i; -+ UINT8 tmpc; -+ -+ // wait until the input buffer is empty -+ for (i = 0; i < loop_limit; i++) { -+ tmpc = inlpc(KBC_STATUS); -+ if ((tmpc & BIT_IBF) == 0) -+ break; -+ } -+ -+ outlpc(KBC_CMD, cmd); -+} -+ -+static void kbc_wdata(UINT8 wdata) -+{ -+ int loop_limit = 1000; -+ int i; -+ UINT8 tmpc; -+ -+ // wait until the input buffer is empty -+ for (i = 0; i < loop_limit; i++) { -+ tmpc = inlpc(KBC_STATUS); -+ if ((tmpc & BIT_IBF) == 0) -+ break; -+ } -+ -+ outlpc(KBC_DATA, wdata); -+} -+ -+static UINT8 kbc_rdata(void) -+{ -+ int loop_limit = 1000; -+ int i; -+ UINT8 rdata; -+ UINT8 tmpc; -+ -+ // wait until the output buffer is not empty -+ for (i = 0; i < loop_limit; i++) { -+ tmpc = inlpc(KBC_STATUS); -+ if (tmpc & BIT_OBF) -+ break; -+ } -+ -+ rdata = inlpc(KBC_DATA); -+ return (rdata); -+} -+ -+static void delay_loop(int max_no) -+{ -+ int i; -+ -+ for (i = 0; i < max_no; i++) ; -+} -+ -+static UINT8 get_response(void) -+{ -+ UINT8 tmpc; -+ -+ delay_loop(200000); -+ tmpc = kbc_rdata(); -+ return (tmpc); -+} -+ -+int it8718f_init(void) -+{ -+ static int initialized = 0; -+ UINT8 tmpc; -+ unsigned int chip_id; -+ -+ if (initialized == 1) -+ return (0); -+ -+ // Enter the configuration mode -+ outlpc(ITE_ADDR, 0x87); -+ outlpc(ITE_ADDR, 0x01); -+ outlpc(ITE_ADDR, 0x55); -+ outlpc(ITE_ADDR, 0x55); -+ -+ // Check the chip ID -+ printk("Check IT8718F chip ID => "); -+ outlpc(ITE_ADDR, 0x20); -+ tmpc = inlpc(ITE_DATA); -+ chip_id = (tmpc & 0xff) << 8; -+ outlpc(ITE_ADDR, 0x21); -+ tmpc = inlpc(ITE_DATA); -+ chip_id |= tmpc & 0xff; -+ -+ if (chip_id != 0x8718) { -+ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, -+ chip_id & 0xff); -+ return (1); -+ } else -+ printk("PASSED\n"); -+ -+ // KBC Self Test -+ printk("KBC self-test => "); -+ kbc_cmd(0xaa); -+ tmpc = kbc_rdata(); -+ if (tmpc != 0x55) { -+ printk("FAILED with code = 0x%C\n", tmpc & 0xff); -+ return (2); -+ } else -+ printk("PASSED\n"); -+ -+ // KBC Interface Test -+ printk("KBC interface test => "); -+ kbc_cmd(0xab); -+ tmpc = kbc_rdata(); -+ switch (tmpc) { -+ case 0: -+ printk("PASSED\n"); -+ break; -+ -+ case 1: -+ printk("FAILED as the clock is stuck low\n"); -+ return (3); -+ -+ case 2: -+ printk("FAILED as the clock is stuck high\n"); -+ return (3); -+ -+ case 3: -+ printk("FAILED as the data is stuck low\n"); -+ return (3); -+ -+ case 4: -+ printk("FAILED as the data is stuck high\n"); -+ return (3); -+ -+ default: -+ printk("FAILED with unknown error\n"); -+ return (3); -+ break; -+ } -+ -+ // Read the KBC mode -+ kbc_cmd(0xca); -+ tmpc = kbc_rdata(); -+ -+ // Set KBC to the PS/2 mode -+ tmpc |= 0x01; -+ kbc_cmd(0xcb); -+ kbc_wdata(tmpc); -+ -+ // Enable keyboard -+ kbc_wdata(0xf4); -+ tmpc = get_response(); -+ printk("@@@@@ : Response of enabling keyboard = 0x%x\n", tmpc & 0xff); -+ -+ // Enable mouse -+ kbc_cmd(0xd4); -+ kbc_wdata(0xf4); -+ tmpc = get_response(); -+ //outmsg("Response of enabling mouse = 0x%C\n", tmpc & 0xff); -+ -+ // bit 6: translate -+ // bit 5: mouse enable -+ // bit 4: keyboard enable -+ // bit 3: ignore keyboard lock -+ // bit 2: system flag -+ // bit 1: mouse interrupt enable -+ // bit 0: Keyboard interrupt enable -+ kbc_cmd(0x60); -+ kbc_wdata(0x47); -+ -+ // Set repeat rate and delay -+ kbc_wdata(0xf3); -+ kbc_wdata(0x00); -+ tmpc = get_response(); -+ -+ // Set LDN = 5 (Keyboard) -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x05); -+ -+ // KBC clock = 8MHz, Key lock enabled, interrupt type can be changed -+ outlpc(ITE_ADDR, 0xf0); -+ outlpc(ITE_DATA, 0x4e); -+ -+ // Low-level triggered interrupt -+ outlpc(ITE_ADDR, 0x71); -+ outlpc(ITE_DATA, 0x01); -+ -+ // Set LDN = 6 (Mouse) -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x06); -+ -+ // Enable mouse -+ outlpc(ITE_ADDR, 0x30); -+ outlpc(ITE_DATA, 0x01); -+ -+ // Interrupt type can be changed -+ outlpc(ITE_ADDR, 0xf0); -+ outlpc(ITE_DATA, 0x01); -+ -+ // Low-level triggered interrupt -+ outlpc(ITE_ADDR, 0x71); -+ outlpc(ITE_DATA, 0x01); -+ -+ // Exit the configuration mode -+ outlpc(ITE_ADDR, 0x02); -+ outlpc(ITE_DATA, 0x02); -+ -+ initialized = 1; -+ return (0); -+} -+ -+//INT for lpc -+/* Turn the interrupt source on. */ -+void UnmaskIRQ(UINT32 IRQ) -+{ -+ volatile UINT32 *IRQBase; -+ -+ IRQBase = (UINT32 *) CPE_IC_BASE; -+ -+ IRQBase[(IRQ_MASK / sizeof(UINT32))] |= (1 << IRQ); -+} -+ -+void EnableIRQ() -+{ -+ -+ __asm__ volatile ("setgie.d\n\t" -+ "isb\n\t" -+ "mfsr $r1, $INT_MASK\n\t" -+ "ori $r1, $r1, #0x3f\n\t" -+ "mtsr $r1, $INT_MASK\n\t" -+ "setgie.e\n\t" "isb\n\t"); -+ -+} -+ -+void SetIRQmode(UINT32 IRQ, UINT32 edge) -+{ -+ volatile UINT32 *IRQBase; -+ -+ IRQBase = (UINT32 *) CPE_IC_BASE; -+ -+ if (edge) -+ IRQBase[(IRQ_MODE / sizeof(UINT32))] |= (1 << IRQ); -+ else -+ IRQBase[(IRQ_MODE / sizeof(UINT32))] &= ~(1 << IRQ); -+} -+ -+void SetIRQlevel(UINT32 IRQ, UINT32 low) -+{ -+ volatile UINT32 *IRQBase; -+ -+ IRQBase = (UINT32 *) CPE_IC_BASE; -+ -+ if (low) -+ IRQBase[(IRQ_LEVEL / sizeof(UINT32))] |= (1 << IRQ); -+ else -+ IRQBase[(IRQ_LEVEL / sizeof(UINT32))] &= ~(1 << IRQ); -+} -+ -+BOOL SetIntTrig(UINT32 intNum, int intMode, int intLevel) -+{ -+ if (intNum >= 32) { -+ printk("ERROR: The interrupt number %d is incorrect\n", intNum); -+ return FALSE; -+ } else { -+ SetIRQmode(intNum, intMode); -+ SetIRQlevel(intNum, intLevel); -+ return TRUE; -+ } -+} -+ -+BOOL EnableInt(UINT32 intNum) -+{ -+ -+ if (intNum >= 32) { -+ printk("ERROR: The interrupt number %d is incorrect\n", intNum); -+ return FALSE; -+ } else { -+ IRQSources |= 1 << intNum; -+ UnmaskIRQ(intNum); -+ EnableIRQ(); -+ return TRUE; -+ } -+} -+ -+//End INT for lpc -+ -+void enable_sirq(void) -+{ -+ UINT32 data; -+ -+ // Unmask SERIRQs of Keyboard and Mouse -+ data = inw(CPE_LPCREG_BASE + LPC_REG_SIMR); -+ data &= ~((1 << SIRQ_KB) | (1 << SIRQ_MS)); -+ outw(CPE_LPCREG_BASE + LPC_REG_SIMR, data); -+ -+ // Enable SERIRQ -+ data = inw(CPE_LPCREG_BASE + LPC_REG_SCR); -+ data |= 0x1; -+ outw(CPE_LPCREG_BASE + LPC_REG_SCR, data); -+} -+ -+void ite_set_pme() -+{ -+ -+ UINT8 tmpc; -+ unsigned int chip_id; -+ // Enter the configuration mode -+ outlpc(ITE_ADDR, 0x87); -+ outlpc(ITE_ADDR, 0x01); -+ outlpc(ITE_ADDR, 0x55); -+ outlpc(ITE_ADDR, 0x55); -+ -+ // Check the chip ID -+ printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n"); -+ outlpc(ITE_ADDR, 0x20); -+ tmpc = inlpc(ITE_DATA); -+ chip_id = (tmpc & 0xff) << 8; -+ outlpc(ITE_ADDR, 0x21); -+ tmpc = inlpc(ITE_DATA); -+ chip_id |= tmpc & 0xff; -+ -+ printk("@@@@@ : chip_id = 0x%08x\n", chip_id); -+ if (chip_id != 0x8718) { -+ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, -+ chip_id & 0xff); -+ return (1); -+ } else -+ printk("@@@@@ : PASSED\n"); -+ -+ // Set LDN = 5 -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x05); -+ -+ //Read index 30 -+ outlpc(ITE_ADDR, 0x30); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x30] = 0x%x\n", tmpc); -+ //Set index 30 bit0 = 0; -+ outlpc(ITE_ADDR, 0x30); -+ outlpc(ITE_DATA, tmpc & 0xFE); -+ -+ // Set LDN = 6 -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x06); -+ -+ //Read index 30 -+ outlpc(ITE_ADDR, 0x30); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x30] = 0x%x\n", tmpc); -+ //Set index 30 bit0 = 0; -+ outlpc(ITE_ADDR, 0x30); -+ outlpc(ITE_DATA, tmpc & 0xFE); -+ -+ // Set LDN = 4 for PME -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x04); -+ -+ //Read index F0 -+ outlpc(ITE_ADDR, 0xF0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF0] = 0x%x\n", tmpc); -+ //Set index F0 BIT[4:3]=1; -+ outlpc(ITE_ADDR, 0xF0); -+ outlpc(ITE_DATA, tmpc | 0x18); -+ -+ //PME output enable -+ //Read index F2 -+ outlpc(ITE_ADDR, 0xF2); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF2] = 0x%x\n", tmpc); -+ //Set index F2 bit6=0; -+ outlpc(ITE_ADDR, 0xF2); -+ outlpc(ITE_DATA, tmpc & 0xBF); -+ -+ // Exit the configuration mode -+ outlpc(ITE_ADDR, 0x02); -+ outlpc(ITE_DATA, 0x02); -+} -+ -+void get_keyboard_status() -+{ -+ -+ printk("Getting keyboard status....\n"); -+ -+ UINT8 tmpc; -+ unsigned int chip_id; -+ -+ // Enter the configuration mode -+ outlpc(ITE_ADDR, 0x87); -+ outlpc(ITE_ADDR, 0x01); -+ outlpc(ITE_ADDR, 0x55); -+ outlpc(ITE_ADDR, 0x55); -+ -+ // Check the chip ID -+ //printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n"); -+ outlpc(ITE_ADDR, 0x20); -+ tmpc = inlpc(ITE_DATA); -+ chip_id = (tmpc & 0xff) << 8; -+ outlpc(ITE_ADDR, 0x21); -+ tmpc = inlpc(ITE_DATA); -+ chip_id |= tmpc & 0xff; -+ -+ //printk("@@@@@ : chip_id = 0x%08x\n", chip_id); -+ if (chip_id != 0x8718) { -+ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, -+ chip_id & 0xff); -+ return (1); -+ } -+ // Set LDN = 4 for PME -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x04); -+ -+ ///////// Dump configuration register -+ outlpc(ITE_ADDR, 0xf1); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf1] = 0x%x\n", tmpc); -+ -+ ///////// Dump configuration register -+ outlpc(ITE_ADDR, 0xf0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf0] = 0x%x\n", tmpc); -+ -+} -+ -+void get_lpc_value() -+{ -+ UINT8 tmpc; -+ unsigned int chip_id; -+ -+ // Enter the configuration mode -+ outlpc(ITE_ADDR, 0x87); -+ outlpc(ITE_ADDR, 0x01); -+ outlpc(ITE_ADDR, 0x55); -+ outlpc(ITE_ADDR, 0x55); -+ -+ // Check the chip ID -+ printk("@@@@@ : Check IT8718F chip ID in get_lpc_value => \n"); -+ outlpc(ITE_ADDR, 0x20); -+ tmpc = inlpc(ITE_DATA); -+ chip_id = (tmpc & 0xff) << 8; -+ outlpc(ITE_ADDR, 0x21); -+ tmpc = inlpc(ITE_DATA); -+ chip_id |= tmpc & 0xff; -+ -+ printk("@@@@@ : chip_id = 0x%08x\n", chip_id); -+ if (chip_id != 0x8718) { -+ printk("FAILED with chip ID = 0x%C%C.\n", (chip_id >> 8) & 0xff, -+ chip_id & 0xff); -+ return (1); -+ } else -+ printk("@@@@@ : PASSED\n"); -+ -+ printk("=================== Get Values ==================\n"); -+ //////////// Environment Controller configuration register -+ printk("@@@@@ : Environment Controller configuration register\n"); -+ // Set LDN = 4 for PME -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x04); -+ -+ printk("@@@@@ : LDN = 4\n"); -+ -+ ///////// Dump configuration register -+ outlpc(ITE_ADDR, 0x30); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x30] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x60); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x60] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x61); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x61] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x62); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x62] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x63); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x63] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x70); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x70] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf0] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf1); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf1] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf2); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf2] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf3); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf3] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf4); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf4] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf5); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf5] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf6); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf6] = 0x%x\n", tmpc); -+ -+ //////////// Keyboard configuration register -+ printk("@@@@@ : Keyboard configuration register\n"); -+ // Set LDN = 5 -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x05); -+ -+ printk("@@@@@ : LDN = 5\n"); -+ -+ outlpc(ITE_ADDR, 0x30); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x30] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x60); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x60] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x61); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x61] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x62); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x62] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x63); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x63] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x70); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x70] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x71); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x71] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xf0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xf0] = 0x%x\n", tmpc); -+ -+ //////////// GPIO configuration register -+ printk("@@@@@ : GPIO configuration register\n"); -+ // Set LDN = 7 for GPIO -+ outlpc(ITE_ADDR, 0x07); -+ outlpc(ITE_DATA, 0x07); -+ -+ printk("@@@@@ : LDN = 7\n"); -+ -+ outlpc(ITE_ADDR, 0x60); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x60] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x62); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x62] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x63); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x63] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x64); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x64] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x65); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x65] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x70); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x70] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x71); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x71] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x72); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x72] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x73); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x73] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0x74); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0x74] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB0] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB1); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB1] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB2); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB2] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB3); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB3] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB4); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB4] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB5); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB5] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xB8); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xB8] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xBA); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xBA] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xBB); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xBB] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xBC); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xBC] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xBD); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xBD] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC0] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC1); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC1] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC2); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC2] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC3); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC3] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC4); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC4] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC5); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC5] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC8); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC8] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xC9); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xC9] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xCA); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xCA] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xCB); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xCB] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xCC); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xCC] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xCD); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xCD] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE0] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE1); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE1] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE2); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE2] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE3); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE3] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE4); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE4] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE5); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE5] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xE6); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xE6] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF0); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF0] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF1); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF1] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF2); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF2] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF3); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF3] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF4); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF4] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF5); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF5] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF6); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF6] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF7); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF7] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF8); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF8] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xF9); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xF9] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xFA); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xFA] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xFB); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xFB] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xFC); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xFC] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xFD); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xFD] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xFE); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xFE] = 0x%x\n", tmpc); -+ -+ outlpc(ITE_ADDR, 0xFF); -+ tmpc = inlpc(ITE_DATA); -+ printk("[0xFF] = 0x%x\n", tmpc); -+ -+ printk("=================== End Get Values ==================\n"); -+ -+} -+ -+/////////////////////////////// End LPC wake up /////////////////////////////////////////////// -+ -+/* -+ * AG102 PMU sleep mode handler. -+ */ -+void andes_suspend_to_ram() -+{ -+ int i, k, l, checksum, checksuma; -+ unsigned int addr, reg; -+ static int irq_saves[3]; -+ unsigned int tmp; -+ pgd_t *pgdv; -+ pud_t *pudv; -+ pmd_t *pmdv; -+ pte_t *ptev; -+ unsigned int resume_addr /*, resume_temp */ ; -+ //unsigned int *resume_tempaddr; -+ __asm__ volatile ("mfsr %0, $ir14\n\t":"=&r" (tmp)); -+ //printk("\nag102_cpu_resume:0x%x\n", ag102_cpu_resume); -+ //printk( KERN_WARNING "\nag102_cpu_resume2:0x%x\n", ag102_cpu_resume2); -+ pgdv = -+ (pgd_t *) __va((GET_L1_PPTB() & L1_PPTB_mskBASE)) + -+ pgd_index((unsigned int)ag102_cpu_resume); -+ pudv = pud_offset(pgdv, (unsigned int)ag102_cpu_resume); -+ pmdv = pmd_offset(pudv, (unsigned int)ag102_cpu_resume); -+ ptev = pte_offset_map(pmdv, (unsigned int)ag102_cpu_resume); -+ //printk("ag102_cpu_resume pte:0x%x\n", ptev); -+ resume_addr = -+ ((*ptev) & TLB_DATA_mskPPN) | ((unsigned int)ag102_cpu_resume & -+ 0x00000fff); -+ printk("resume_addr using Page Table :0x%08x\n", resume_addr); -+ -+ //ADD by river 2010.09.23 -+ printk("@@@@@ resume_addr(VA):0x%08x\n", ag102_cpu_resume); -+ printk("@@@@@ resume_addr2(VA):0x%08x\n", ag102_cpu_resume2); -+ printk("@@@@@ resume_addr(PA) using virt_to_phys :0x%08x\n", -+ virt_to_phys(ag102_cpu_resume)); -+ printk("@@@@@ resume_addr2(PA):0x%08x\n", -+ virt_to_phys(ag102_cpu_resume2)); -+ printk("@@@@@ AHB Controller for ROM :0x%08x\n", -+ REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x10)); -+ printk("@@@@@ AHB Controller for RAM :0x%08x\n", -+ REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x18)); -+ //End ADD by river 2010.09.23 -+ -+ /* trigger mode regs */ -+ irq_saves[0] = REG32(AMIC_VA_BASE + 0x20); -+ /* trigger level regs */ -+ irq_saves[1] = REG32(AMIC_VA_BASE + 0x24); -+ /* interrupt enable regs */ -+ irq_saves[2] = REG32(AMIC_VA_BASE + 0x80); -+ /* save SDRAM settings */ -+ -+ /* set resume return address */ -+ //REG32(PCU_VA_BASE + 0x400) = (resume_addr); -+ REG32(PCU_VA_BASE + 0x400) = (resume_addr) | 0x80000000; -+ REG32(PCU_VA_BASE + 0x404) = (u32) ag102_cpu_resume2; -+ REG32(PCU_VA_BASE + 0x410) = GET_L1_PPTB(); -+ //ADD by river 2010.12.02 for reserve kernel remap -+ REG32(PCU_VA_BASE + 0x418) = REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x10); -+ REG32(PCU_VA_BASE + 0x41C) = REG32(AHB_ATFAHBC020S_0_VA_BASE + 0x18); -+ //End ADD by river 2010.12.02 for reserve kernel remap -+ printk("L1_PPTB (PA) =0x%08x\n", GET_L1_PPTB()); -+ printk("L1_PPTB (VA) in virtual address =0x%08x\n", -+ phys_to_virt(GET_L1_PPTB())); -+ -+ //ADD by river 2010.12.07 -+ UINT32 phy_id, phy_addr; -+ ETH_PHY_STAT phy_stat; -+ -+ if (eth_phy_detect(&phy_addr, &phy_id) != 0) { -+ printk("ERR: fail to detect known PHY!!!\n"); -+ return; -+ } -+ //TEST by river 2010.12.10 -+ eth_phy_init(phy_addr); -+ eth_phy_stat(phy_addr, &phy_stat); -+ eth_mac_init(&phy_stat); -+ //End TEST by river 2010.12.10 -+ gmac_set_wol(); -+ //End ADD by river 2010.12.07 -+ -+ /////////// ADD by river 2010.12.20 for LPC wakeup ///////////////////////////// -+ if (it8718f_init() != 0) -+ return; -+ -+ //INTC setup -+ SetIntTrig(IRQ_LPC, LEVEL, H_ACTIVE); -+ EnableInt(IRQ_LPC); // including INT_MASK and GIE in Core -+ -+ enable_sirq(); -+ -+ //__asm__ volatile ("1:\n\t"); -+ //__asm__ volatile ("b 1b\n\t"); -+ -+ printk("Calling ite_set_pme() YAYAYA....\n"); -+ ite_set_pme(); -+ -+ printk("Get Value..... YAYAYA....1\n"); -+ get_lpc_value(); -+ -+ /////////// End ADD by river 2010.12.20 for LPC wakeup ///////////////////////////// -+ -+ //set GPIO[2] as suspend2dram power control pin -+ PCU_SET_FIELD(MFPS1, SUSPEND_GPIO, 0x1); -+ PCU_SET_FIELD(PCS9_PDD, SUSP2RAM, 0x1); -+ //ADD by river 2010.12.07 -+ PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, PCS_WKEN_WOL | PCS_WKEN_LPC | PCS_WKEN_RTC)); // use only gpio0 and wol -+ //PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, PCS_WKEN_LPC)); // use lpc -+ -+ //End ADD by river 2010.12.07 -+ -+ /* set pwoer status */ -+ //int par = PCS_POWER_GPU_AND_DAC|PCS_POWER_CPUB; -+ int reg_tmp = PCU_PREPARE(PCS9_PARA, IE, 0x1) | -+ PCU_PREPARE(PCS9_PARA, CMD, -+ PCS_CMD_PW_DOWN /*PCS_CMD_SCALING|PCS_CMD_DRAM_SF */ ) | -+ PCU_PREPARE(PCS9_PARA, SYNC, PCS_SYNC_SRC) | PCU_PREPARE(PCS9_PARA, NXTPAR, 0 /*par */ ); // change power status -+ PCU_SET_REG(PCS9_PARA, reg_tmp); -+ -+ //PCU_SET_FIELD(MFPS1, SUSPEND_GPIO, 0x1); -+ /* setup wakeup sources */ -+ /* -+ k = PCU_PREPARE(WAKEUP_SEN, GPIO0_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, GPIO1_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, GPIO2_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, GPIO3_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, GPIO4_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, GPIO5_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, WOL_POL, 0x1) | -+ PCU_PREPARE(WAKEUP_SEN, LPC_POL, 0x1); -+ l = ~k; //set polarity -+ //l = 0x1c0; -+ PCU_SET_REG(WAKEUP_SEN, l); -+ PCU_SET_REG(PCS9_CFG, PCU_PREPARE(PCS9_CFG, WKEN, k)); -+ */ -+ /* Set PDD register and set suspend_to_ram */ -+ //PCU_SET_FIELD(PCS9_PDD, SUSP2RAM, 0x1); -+ -+ cpu_dcache_wbinval_all(); -+ cpu_icache_inval_all(); -+ SET_CACHE_CTL(GET_CACHE_CTL() & ~CACHE_CTL_mskDC_EN); -+ -+ /* lock self-refresh code to L1 cache */ -+ -+ addr = (unsigned int)__SELF_REFRESH_LOCK_START; -+ reg = (((unsigned int)__SELF_REFRESH_LOCK_END - (unsigned int)__SELF_REFRESH_LOCK_START) >> 5) + 1; // -+ -+ for (i = 0; i < reg; i++) { -+ __asm__ volatile ("li $p0, 0x0\n\t" -+ "add $p0, $p0, %0\n\t" -+ "cctl $p0, L1I_VA_FILLCK\n\t" -+ "isb\n\t"::"r" (addr)); -+ -+ addr += 32; -+ } -+ -+ unsigned char *ptr; -+ //ADD by river 2010.11.19 -+ printk("The resume address's content is :\n"); -+ ptr = (unsigned char *)ag102_cpu_resume; -+ for (i = 0; i < 20; i++) { -+ printk("0x%02x - ", *ptr++); -+ } -+ -+ printk("Get Value..... YAYAYA....2\n"); -+ get_lpc_value(); -+ -+ //End ADD by river 2010.11.19 -+ ag102_cpu_sleep(); -+ printk("return success-1..........\n"); -+ /* wakeup and ckeck */ -+ /* -+ reg_tmp = PCU_GET_REG(PCS9_ST2);// check Status-2 -+ if (PCU_EXTRACT(PCS9_ST2, CURPAR, reg_tmp) != par) -+ printk("Parameter setup is not the same!\n"); -+ -+ reg_tmp = PCU_GET_REG(PCS9_ST1); // check Status-1 -+ if (PCU_EXTRACT(PCS9_ST1, STS, reg_tmp) != PCS_STS_DONE) -+ printk("The work is not done?!\n"); -+ if (PCU_EXTRACT(PCS9_ST1, ERR, reg_tmp) != PCS_ERR_NONE) -+ printk("Some error happened!!\n"); -+ PCU_SET_REG(PCS9_ST1, 0x0); //clear status -+ -+ */ -+ ftpci_postinit(); -+ SET_CACHE_CTL(GET_CACHE_CTL() | CACHE_CTL_mskDC_EN); -+ /* trigger mode regs */ -+ REG32(AMIC_VA_BASE + 0x20) = irq_saves[0]; -+ /* trigger level regs */ -+ REG32(AMIC_VA_BASE + 0x24) = irq_saves[1]; -+ /* interrupt enable regs */ -+ REG32(AMIC_VA_BASE + 0x80) = irq_saves[2]; -+ __asm__ volatile ("mtsr %0, $ir14\n\t"::"r" (tmp)); -+ -+ printk("return success-2..........\n"); -+ dump_stack(); -+ -+} -+ -+static int ag102_pm_valid(suspend_state_t state) -+{ -+ switch (state) { -+ case PM_SUSPEND_ON: -+ case PM_SUSPEND_STANDBY: -+ case PM_SUSPEND_MEM: -+ return 1; -+ -+ default: -+ return 0; -+ } -+} -+ -+static int ag102_pm_begin(suspend_state_t state) -+{ -+ /* TBD if we need it */ -+ return 0; -+} -+ -+static void andes_suspend_cpu(void) -+{ -+ unsigned int irq_save; -+ /* setup GPIO interrupt enable regs to enable GPIO0 */ -+ REG32(GPIO_VA_BASE + 0x20) = 1; -+ /* save interrupt enable regs */ -+ irq_save = REG32(AMIC_VA_BASE + 0x80); -+ /* accept all interrupts to wake up except timer interrupt */ -+ REG32(AMIC_VA_BASE + 0x80) &= ~(1 << 19); -+ /* enable UART0 interrupt */ -+ REG32(AMIC_VA_BASE + 0x80) |= 1 << 13; -+ -+ /* -+ * for more IRQ info, please refer to -+ * arch/nds32/include/asm/spec.h&spec-ag102.h -+ */ -+ -+ __asm__ volatile ("standby no_wake_grant\n\t"); -+ /* clear GPIO interrupt */ -+ REG32(GPIO_VA_BASE + 0x30) = 1; -+ /* disable GPIO interrupt */ -+ REG32(GPIO_VA_BASE + 0x20) = 0; -+ /* restore GPIO enable regs */ -+ REG32(AMIC_VA_BASE + 0x80) = irq_save; -+} -+ -+static int ag102_pm_enter(suspend_state_t state) -+{ -+ switch (state) { -+ case PM_SUSPEND_STANDBY: -+ andes_suspend_cpu(); -+ return 0; -+ case PM_SUSPEND_MEM: -+ printk("@@@@@@@@@@ : ag102_pm_enter()... from gavin.......\n"); -+ andes_suspend_to_ram(); -+ return 0; -+ default: -+ return -EINVAL; -+ } -+} -+ -+/* -+ * Called after processes are frozen, but before we shutdown devices. -+ */ -+static int ag102_pm_prepare(void) -+{ -+ /* TBD if we need it */ -+ return 0; -+} -+ -+/* -+ * Called after devices are wakeuped, but before processes are thawed. -+ */ -+static void ag102_pm_finish(void) -+{ -+ /* TBD if we need it */ -+} -+ -+static void ag102_pm_end(void) -+{ -+ /* TBD if we need it */ -+#if 0 -+ class_destroy(andes_pcu_class); -+ unregister_chrdev(andes_pcu_major, ANDES_PCU_STRING); -+#endif -+ printk("pm_exit\n"); -+} -+ -+static int andes_pcu_ioctl(struct inode *inode, struct file *file, -+ unsigned int cmd, unsigned long arg) -+{ -+ return 0; -+} -+ -+static int andes_pcu_open(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+static ssize_t andes_pcu_write(struct file *filp, const char *buff, -+ size_t count, loff_t * ppos) -+{ -+ char data; -+ get_user(data, buff); -+ switch (data) { -+ case 's': -+ printk("Just suspend cpu\n"); -+ andes_suspend_cpu(); -+ break; -+ case 'm': -+ printk("Suspend to ram\n"); -+ andes_suspend_to_ram(); -+ break; -+ } -+ return 0; -+} -+ -+static int andes_pcu_release(struct inode *inode, struct file *file) -+{ -+ return 0; -+} -+ -+static struct file_operations andes_pcu_fops = { -+ .owner = THIS_MODULE, -+ .ioctl = andes_pcu_ioctl, -+ .open = andes_pcu_open, -+ .write = andes_pcu_write, -+ .release = andes_pcu_release, -+}; -+ -+static struct platform_suspend_ops ag102_pm_ops = { -+ .valid = ag102_pm_valid, -+ .begin = ag102_pm_begin, -+ .prepare = ag102_pm_prepare, -+ .enter = ag102_pm_enter, -+ .finish = ag102_pm_finish, -+ .end = ag102_pm_end, -+}; -+ -+//PCU power-off workaround { -+#undef IRQ_LEVEL -+#include -+#include -+ -+//#define PM_DEBUG -+#ifdef PM_DEBUG -+#define PRINTK printk -+#else -+#define PRINTK(...) -+#endif -+ -+static volatile int pcuirq = 0; -+ -+static inline void poweroff_pcu(void) -+{ -+ PRINTK(KERN_INFO "[kernel] poweroff_pcu()"); -+ REG32(PCU_VA_BASE + 0x1a4) = (2 << 28) | (1 << 24) | (6 << 0); //power-down, sync CPUA, domain GPU+CPUB -+ __asm__ volatile ("standby wait_done\n"); -+ REG32(PCU_VA_BASE + 0x1a8) = 0x0; //PCS9 status normal, no error -+} -+ -+static inline void clear_pcu_status(void) -+{ -+ PRINTK(KERN_INFO "[kernel] clear_pcu_status()"); -+ REG32(PCU_VA_BASE + 0x1b0) |= (1 << 31); //clear poweroff flag -+ asm("msync store\nisb"); -+} -+ -+static irqreturn_t gpio0_isr(int irq, void *dev_id) -+{ -+ PRINTK(KERN_INFO "[kernel] gpio0_isr(irq=%d)\n", irq); -+ -+ // is GPIO0 IRQ -+ if (REG32(GPIO_VA_BASE + 0x28) & (1 << 0)) { -+ PRINTK(KERN_INFO "GPIO#0 ASSERT!\n"); -+ -+ pcuirq = 0; -+ -+ //disable GPIO0 IRQ -+ REG32(GPIO_VA_BASE + 0x2c) |= (1 << 0); //GPIO0 IRQ mask, level mode AMIC.GPIO#0 also cleared -+ -+// REG32(AMIC_VA_BASE + 0x84) = (1<<13); //AMIC clear GPIO interrupt -+ -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+#define GPIO_SEC (1<<11) -+static irqreturn_t pcu_isr(int irq, void *dev_id) -+{ -+ UINT32 status = REG32(PCU_VA_BASE + 0x94); -+ PRINTK(KERN_INFO "[kernel] pcu_isr(irq=%d) status=0x%08x\n", irq, -+ status); -+ if (0 == (GPIO_SEC & status)) -+ return IRQ_NONE; -+ -+ PRINTK(KERN_INFO "[kernel] GPIO_SEC\n"); -+ clear_pcu_status(); //clear PCS9 IRQ (level mode => AMIC.PCU also cleared) -+ pcuirq++; -+ if (1 == pcuirq) { -+ //enable GPIO0 IRQ -+ REG32(GPIO_VA_BASE + 0x30) = (1 << 0); //GPIO0 IRQ cleared -+// REG32(AMIC_VA_BASE + 0x84) = (1 << 13); //AMIC clear GPIO interrupt -+// enable_irq(GPIO_FTGPIO010_IRQ); -+ REG32(AMIC_VA_BASE + 0x80) |= (1 << 13); //AMIC enable GPIO IRQ -+ REG32(GPIO_VA_BASE + 0x2c) &= ~(1 << 0); //GPIO0 IRQ unmask -+ } else if (5 == pcuirq) { -+ poweroff_pcu(); -+ } -+// REG32(AMIC_VA_BASE + 0x84) = (1 << 8); //PCU IRQ clear -+ -+ return IRQ_HANDLED; -+} -+ -+//PCU power-off workaround } -+ -+static int __init ag102_pm_init(void) -+{ -+ int ret = 0; -+ struct device *temp_class; -+ printk("PM driver init\n"); -+ suspend_set_ops(&ag102_pm_ops); -+ -+ andes_pcu_major = register_chrdev(0, ANDES_PCU_STRING, &andes_pcu_fops); -+ -+ printk("@@@@@ : andes_pcu_major = 0x%08x\n", andes_pcu_major); -+ if (andes_pcu_major < 0) { -+ printk("Unable to get a major for andes pcu driver!\n"); -+ return andes_pcu_major; -+ } -+ -+ andes_pcu_class = class_create(THIS_MODULE, ANDES_PCU_STRING); -+ -+ if (IS_ERR(andes_pcu_class)) { -+ printk(KERN_ERR "Error creating andes pcu class.\n"); -+ ret = PTR_ERR(andes_pcu_class); -+ goto err_out1; -+ } -+ -+ temp_class = device_create(andes_pcu_class, NULL, -+ MKDEV(andes_pcu_major, 0), -+ NULL, ANDES_PCU_STRING); -+ -+ if (IS_ERR(temp_class)) { -+ printk(KERN_ERR "Error creating andes pcu class device.\n"); -+ ret = PTR_ERR(temp_class); -+ goto err_out2; -+ } -+ -+ mac_dah = GMAC_GET_REG(MAC_MADR); -+ mac_dal = GMAC_GET_REG(MAC_LADR); -+ -+ //poweroff workaround -+ { -+ if (request_irq -+ (PCU_IRQ, pcu_isr, IRQF_SHARED, "PCU_POWEROFF", pcu_isr)) { -+ printk("Failed to request PCU interrupt.\n"); -+ } -+ -+ if (request_irq -+ (GPIO_FTGPIO010_IRQ, gpio0_isr, IRQF_SHARED, -+ "GPIO0_FOR_PCU", gpio0_isr)) { -+ printk("Failed to request GPIO0 interrupt.\n"); -+ } -+ -+ REG32(PCU_VA_BASE + 0x1b0) |= (3 << 28); //poweroff in 5s -+ -+ //AMIC setup -+ // PCU IRQ default edge trigger, rising edge -+ // GPIO_FTGPIO010_IRQ default edge trigger, rising edge -+// REG32(AMIC_VA_BASE + 0x20) &= ~(1 << 8); //PCU IRQ level trigger -+// REG32(AMIC_VA_BASE + 0x24) &= ~(1 << 8); //PCU IRQ active-high -+// REG32(AMIC_VA_BASE + 0x20) &= ~(1 << 13); //GPIO IRQ level trigger -+ -+ //GPIO #0 setup -+ REG32(GPIO_VA_BASE + 0x08) &= ~(1 << 0); //GPIO0 input -+ REG32(GPIO_VA_BASE + 0x18) &= ~(1 << 0); //GPIO0 not pulled (external pull-high) -+ REG32(GPIO_VA_BASE + 0x2c) |= (1 << 0); //GPIO0 IRQ masked -+ REG32(GPIO_VA_BASE + 0x34) |= (1 << 0); //GPIO0 IRQ level trigger -+// REG32(GPIO_VA_BASE + 0x38) &= ~(1<<0); //GPIO0 IRQ single edge -+ REG32(GPIO_VA_BASE + 0x3c) &= ~(1 << 0); //GPIO0 IRQ high-active -+ REG32(GPIO_VA_BASE + 0x40) |= (1 << 0); //GPIO0 enable bounce -+ REG32(GPIO_VA_BASE + 0x40) = 0xffff; //GPIO bounce time = x/PCLK -+// REG32(GPIO_VA_BASE + 0x30) = (1<<0); //GPIO0 IRQ cleared -+ REG32(GPIO_VA_BASE + 0x20) |= (1 << 0); //GPIO0 IRQ enable -+ -+// enable_irq(PCU_IRQ); -+ REG32(AMIC_VA_BASE + 0x80) |= (1 << 8); //IRQ enabled -+ } -+ -+ printk("pm_init\n"); -+ return 0; -+err_out2: -+ class_destroy(andes_pcu_class); -+err_out1: -+ unregister_chrdev(andes_pcu_major, ANDES_PCU_STRING); -+ return 1; -+} -+ -+//static void resume_to_ccode(void) -+//{ -+// printk("Resume to C code successfully....\n"); -+//} -+ -+late_initcall(ag102_pm_init); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ag102/sleep.S linux-3.4.113/arch/nds32/platforms/ag102/sleep.S ---- linux-3.4.113.orig/arch/nds32/platforms/ag102/sleep.S 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ag102/sleep.S 2016-12-01 20:59:24.376613676 +0100 -@@ -0,0 +1,465 @@ -+#include -+.text -+ -+.globl ag102_cpu_sleep -+.globl ag102_cpu_resume -+.globl ag102_cpu_resume2 -+.globl __SELF_REFRESH_LOCK_START -+.globl __SELF_REFRESH_LOCK_END -+ -+#! 0x94200000; keep r0, r1, r2 -+ .macro putch ch -+ li $r0, #0x94200000 -+ move $r2, \ch -+88: -+ lwi $r1, [$r0+#0x14] -+ srli $r1, $r1, #5 -+ andi $r1, $r1, #0x1 -+ beqz $r1, 88b -+ swi $r2, [$r0] -+ .endm -+#! 0x94200000; keep r3, r4 -+ .macro hex2asc val -+ addi \val, \val, -10 -+ bltz \val, 1f -+ addi \val, \val, 0x41 -+ j 2f -+1: -+ addi \val, \val, 0x3a -+2: -+ .endm -+ -+ .macro print_hex mhex -+ move $r3, \mhex -+ -+ srli $r4, $r3, #28 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ srli $r4, $r3, #24 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ srli $r4, $r3, #20 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ srli $r4, $r3, #16 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ srli $r4, $r3, #12 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ srli $r4, $r3, #8 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ srli $r4, $r3, #4 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ move $r4, $r3 -+ andi $r4, $r4, 0xf -+ hex2asc $r4 -+ putch $r4 -+ .endm -+ -+ag102_cpu_resume2: -+/*1: -+b 1b*/ -+ //MOD by river 2010.10.13 -+ popm $r0, $r19 -+ mtusr $r0, $d0.lo ! $d0 lo byte -+ mtusr $r1, $d0.hi ! $d0 hi byte -+ mtusr $r2, $d1.lo ! $d1 lo byte -+ mtusr $r3, $d1.hi ! $d1 hi byte -+ mtsr $r4, $mr0 -+ mtsr $r5, $mr1 -+ mtsr $r6, $mr4 -+ mtsr $r7, $mr6 -+ mtsr $r8, $mr7 -+ mtsr $r9, $mr8 -+ mtsr $r10, $ir0 -+ mtsr $r11, $ir1 -+ mtsr $r12, $ir2 -+ mtsr $r13, $ir3 -+ mtsr $r14, $ir9 -+ mtsr $r15, $ir10 -+ mtsr $r16, $ir12 -+ mtsr $r17, $ir13 -+ mtsr $r18, $ir14 -+ mtsr $r19, $ir15 -+ //End MOD by river 2010.10.13 -+ popm $r0, $r30 -+ ret -+ -+ag102_cpu_sleep: -+ -+ pushm $r0, $r30 -+ //MOD by river 2010.10.13 -+ mfusr $r0, $d0.lo ! $d0 lo byte -+ mfusr $r1, $d0.hi ! $d0 hi byte -+ mfusr $r2, $d1.lo ! $d1 lo byte -+ mfusr $r3, $d1.hi ! $d1 hi byte -+ mfsr $r4, $mr0 -+ mfsr $r5, $mr1 -+ mfsr $r6, $mr4 -+ mfsr $r7, $mr6 -+ mfsr $r8, $mr7 -+ mfsr $r9, $mr8 -+ mfsr $r10, $ir0 -+ mfsr $r11, $ir1 -+ mfsr $r12, $ir2 -+ mfsr $r13, $ir3 -+ mfsr $r14, $ir9 -+ mfsr $r15, $ir10 -+ mfsr $r16, $ir12 -+ mfsr $r17, $ir13 -+ mfsr $r18, $ir14 -+ mfsr $r19, $ir15 -+ pushm $r0, $r19 -+ //End MOD by river 2010.10.13 -+ -+ /* store $sp to 0x408 scratch pad */ -+ sethi $r0, hi20(PCU_VA_BASE + 0x408) -+ ori $r2, $r0, lo12(PCU_VA_BASE + 0x408) -+ swi $r31, [$r2] -+ -+ /* set signaure "SUSP" to 0x40c */ -+ li $r0, (PCU_VA_BASE + 0x40c) -+ li $r1, 0x53555350 ! set signature "SUSP" to scratch pad register offset 0x40c -+ swi $r1, [$r0] -+ -+ /* -+ * store 8 bytes from 16mb to pcu scratch pad resgister -+ * due to data training process will destroy it -+ */ -+ li $r0, 0x10000 -+ li $r2, (PCU_VA_BASE + 0x414) -+ lwi $r1, [$r0] -+ swi $r1, [$r2] -+ lwi $r1, [$r0 + 0x4] -+ swi $r1, [$r2 + 0x4] -+ -+ /* ADD by river 2010.09.23 */ -+ /* Save PSW in PCU_VA_BASE + 0x420 */ -+ li $r0, (PCU_VA_BASE + 0x420) -+ mfsr $r1, $ir0 -+ swi $r1, [$r0] -+ /* Save $mr0 in PCU_VA_BASE + 0x424 */ -+ li $r0, (PCU_VA_BASE + 0x424) -+ mfsr $r1, $mr0 -+ swi $r1, [$r0] -+ /* Save $mr1 in PCU_VA_BASE + 0x428 */ -+ li $r0, (PCU_VA_BASE + 0x428) -+ mfsr $r1, $mr1 -+ swi $r1, [$r0] -+ /* Save $mr2 in PCU_VA_BASE + 0x42c */ -+ li $r0, (PCU_VA_BASE + 0x42c) -+ mfsr $r1, $mr2 -+ swi $r1, [$r0] -+ /* Save $mr3 in PCU_VA_BASE + 0x430 */ -+ li $r0, (PCU_VA_BASE + 0x430) -+ mfsr $r1, $mr3 -+ swi $r1, [$r0] -+ /* Save $mr4 in PCU_VA_BASE + 0x434 */ -+ li $r0, (PCU_VA_BASE + 0x434) -+ mfsr $r1, $mr4 -+ swi $r1, [$r0] -+ /* Save $mr5 in PCU_VA_BASE + 0x438 */ -+ //li $r0, (PCU_VA_BASE + 0x438) -+ //mfsr $r1, $mr5 -+ //swi $r1, [$r0] -+ /* Save $mr6 in PCU_VA_BASE + 0x43c */ -+ li $r0, (PCU_VA_BASE + 0x43c) -+ mfsr $r1, $mr6 -+ swi $r1, [$r0] -+ /* Save $mr7 in PCU_VA_BASE + 0x440 */ -+ li $r0, (PCU_VA_BASE + 0x440) -+ mfsr $r1, $mr7 -+ swi $r1, [$r0] -+ /* Save $mr8 in PCU_VA_BASE + 0x444 */ -+ li $r0, (PCU_VA_BASE + 0x444) -+ mfsr $r1, $mr8 -+ swi $r1, [$r0] -+ -+ /* Save $ir3 in PCU_VA_BASE + 0x450 */ -+ li $r0, (PCU_VA_BASE + 0x450) -+ mfsr $r1, $ir3 -+ swi $r1, [$r0] -+ -+ /* Save $ir14 in PCU_VA_BASE + 0x454 */ -+ li $r0, (PCU_VA_BASE + 0x454) -+ mfsr $r1, $ir14 -+ swi $r1, [$r0] -+ -+ /* Save $ir15 in PCU_VA_BASE + 0x458 */ -+ li $r0, (PCU_VA_BASE + 0x458) -+ mfsr $r1, $ir15 -+ swi $r1, [$r0] -+ -+ tlbop FlushAll -+ isb -+ /* End ADD by river 2010.09.23 */ -+ -+ //Trace by river 2010.12.01 -+ /*1: -+ b 1b*/ -+ //End Trace by river 2010.12.01 -+.p2align 5 -+__SELF_REFRESH_LOCK_START: -+ /*sethi $r0, hi20(0x900005cc) -+ ori $r0, $r0, lo12(0x900005cc) -+ sethi $r1, hi20(DDR2C_VA_BASE) -+ swi $r0, [$r1+0x4] -+ -+ msync -+ isb -+ -+ standby wake_grant -+ .p2align 5*/ -+ sethi $r0, hi20(DDR2C_VA_BASE) -+ lwi $r1, [$r0+0x4] -+ li $r2, 0x07ffefff -+ and $r1, $r2, $r1 -+ li $r2, 0x90001000 -+ or $r1, $r2, $r1 -+ swi $r1, [$r0+0x4] -+ -+ msync -+ isb -+ -+ standby wake_grant -+ .p2align -+ -+__SELF_REFRESH_LOCK_END: -+ -+ag102_cpu_resume: -+ /* TRACE by river 2010.12.02 */ -+ /*1: -+ b 1b*/ -+ /* End TRACE by river 2010.12.02 */ -+ mfsr $r2, $mr0 -+ ori $r2, $r2, #0x6 -+#ifdef CONFIG_ANDES_PAGE_SIZE_8KB -+ ori $r2, $r2, #0x1 -+#endif -+ mtsr $r2, $mr0 -+ -+ /* ADD by river 2010.09.23 */ -+ li $r3, 'C -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'P -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'U -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'R -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'E -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'S -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'U -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'M -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ li $r3, 'E -+ putch $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ /* ADD by river 2010.09.23 */ -+ -+ /*tlbop FlushAll*/ ! invalidate TLB\n" -+ -+ /* ADD by river 2010.09.23 */ -+ /* restore PSW */ -+ //sethi $r2, hi20(PCU_PA_BASE + 0x420) -+ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x420) -+ //lwi $r3, [$r2] -+ //mtsr $r3, $ir0 -+ //move $p1, $r3 -+ /* restore $mr0 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x424) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x424) -+ lwi $r3, [$r2] -+ mtsr $r3, $mr0 -+ /* restore $mr1 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x428) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x428) -+ lwi $r3, [$r2] -+ mtsr $r3, $mr1 -+ -+ /* restore $mr2 */ -+ //sethi $r2, hi20(PCU_PA_BASE + 0x42c) -+ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x42c) -+ //lwi $r3, [$r2] -+ //mtsr $r3, $mr2 -+ /* restore $mr3 */ -+ //sethi $r2, hi20(PCU_PA_BASE + 0x430) -+ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x430) -+ //lwi $r3, [$r2] -+ //mtsr $r3, $mr3 -+ /* restore $mr4 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x434) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x434) -+ lwi $r3, [$r2] -+ mtsr $r3, $mr4 -+ /* restore $mr5 */ -+ //sethi $r2, hi20(PCU_PA_BASE + 0x438) -+ //ori $r2, $r2, lo12(PCU_PA_BASE + 0x438) -+ //lwi $r3, [$r2] -+ //mtsr $r3, $mr5 -+ /* restore $mr6 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x43c) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x43c) -+ lwi $r3, [$r2] -+ mtsr $r3, $mr6 -+ /* restore $mr7 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x440) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x440) -+ lwi $r3, [$r2] -+ mtsr $r3, $mr7 -+ /* restore $mr8 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x444) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x444) -+ lwi $r3, [$r2] -+ /* ADD by river 2010.12.02 for ICache Enable */ -+ ori $r3, $r3, #0x1 -+ /* End ADD by river 2010.12.02 for ICache Enable */ -+ mtsr $r3, $mr8 -+ -+ /* restore $ir3 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x450) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x450) -+ lwi $r3, [$r2] -+ mtsr $r3, $ir3 -+ -+ move $p1, $r3 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ print_hex $p1 -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ -+ -+ /* restore $ir14 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x454) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x454) -+ lwi $r3, [$r2] -+ mtsr $r3, $ir14 -+ -+ /* restore $ir15 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x458) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x458) -+ lwi $r3, [$r2] -+ mtsr $r3, $ir15 -+ -+ li $r3, '\r -+ putch $r3 -+ li $r3, '\n -+ putch $r3 -+ move $p1, $r3 -+ print_hex $p1 -+ -+ /* End ADD by river 2010.09.23 */ -+ -+ /* in this buggy version(ram locate at 1G) TC01 we don't need to do remap. -+ * ebios set memory locate at 1G & size = 1G, for more detail info, please -+ * refer to ebios boot.S. -+ * -+ * sethi $r2, hi20(0x90c00000 + 0x88) -+ * ori $r2, $r2, lo12(0x90c00000 + 0x88) -+ * movi $r3, #0x1 -+ * swi $r3, [$r2] -+ **/ -+ -+ /* restore 8 bytes from pcu scratch pad resgister to 16mb */ -+ li $r0, 0x10000 -+ li $r2, (PCU_PA_BASE + 0x414) -+ lwi $r1, [$r2] -+ swi $r1, [$r0] -+ lwi $r1, [$r2 + 0x4] -+ swi $r1, [$r0 + 0x4] -+ -+ .p2align 5 -+ resume_lock_start: -+ /* ADD by river 2010.12.02 for ag102_cpu_resume2 for jral.ton $r4, $r4 */ -+ sethi $r2, hi20(PCU_PA_BASE + 0x404) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x404) -+ lwi $r4, [$r2] -+ /* End ADD by river 2010.12.02 for ag102_cpu_resume2 */ -+ -+ /* ADD by river 2010.12.02 for restore kernel ROM map */ -+ sethi $r0, hi20(0x40080000) -+ ori $r0, $r0, lo12(0x40080000) -+ sethi $r1, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x10) -+ ori $r1, $r1, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x10) -+ swi $r0, [$r1] -+ -+ /* ADD by river 2010.12.02 for restore kernel RAM map */ -+ sethi $r0, hi20(0x000A0000) -+ ori $r0, $r0, lo12(0x000A0000) -+ sethi $r1, hi20(AHB_ATFAHBC020S_0_PA_BASE + 0x18) -+ ori $r1, $r1, lo12(AHB_ATFAHBC020S_0_PA_BASE + 0x18) -+ swi $r0, [$r1] -+ -+ /******************* Gavin version ***************************/ -+ //MOD by river 2010.10.13 -+ /*sethi $r2, hi20(PCU_PA_BASE + 0x404) -+ ori $r2, $r2, lo12(PCU_PA_BASE + 0x404) -+ lwi $r4, [$r2] -+ mtsr $r4, $IPC -+ li $r1, 0xcb -+ mtsr $r1, $IPSW -+ iret*/ -+ //End MOD by river 2010.10.13 -+ //End Gavin version//////////////////////////////////////////////////////////// -+ -+ /* End ADD by river 2010.09.23 */ -+ //MOD by river 2010.10.13 -+ //////// jral.ton version //////////////////////////////////////////////////// -+ -+ jral.ton $r4, $r4 -+ .p2align -+ resume_lock_end: -+ //End MOD by river 2010.10.13 -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/amic.c linux-3.4.113/arch/nds32/platforms/amic.c ---- linux-3.4.113.orig/arch/nds32/platforms/amic.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/amic.c 2016-12-01 20:59:24.376613676 +0100 -@@ -0,0 +1,203 @@ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define DEBUG(enabled, tagged, ...) \ -+ do { \ -+ if (enabled) { \ -+ if (tagged) \ -+ printk("[ %30s() ] ", __func__); \ -+ printk(__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+static DEFINE_SPINLOCK(amic_irq_lock); -+ -+static void amic_ack_irq(unsigned int irq) -+{ -+ unsigned int data; -+ -+ spin_lock(&amic_irq_lock); -+ writel(1 << irq, AMIC_BASE + INTSTA); -+ data = readl(AMIC_BASE + INTSTA); -+ spin_unlock(&amic_irq_lock); -+} -+ -+static void amic_mask_irq(unsigned int irq) -+{ -+ unsigned int data; -+ -+ spin_lock(&amic_irq_lock); -+ data = readl(AMIC_BASE + INTEN); -+ data &= ~(1 << irq); -+ writel(data, AMIC_BASE + INTEN); -+ data = readl(AMIC_BASE + INTEN); -+ spin_unlock(&amic_irq_lock); -+} -+ -+static int amic_set_type(unsigned int irq, unsigned int flow_type) -+{ -+ unsigned int data; -+ -+ spin_lock(&amic_irq_lock); -+ if (flow_type & (IRQ_TYPE_EDGE_RISING | IRQ_TYPE_EDGE_FALLING)) { -+ data = readl(AMIC_BASE + INTTRG); -+ data |= 1 << irq; -+ writel(data, AMIC_BASE + INTTRG); -+ } -+ -+ if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_LEVEL_LOW)) { -+ data = readl(AMIC_BASE + INTTRG); -+ data &= ~(1 << irq); -+ writel(data, AMIC_BASE + INTTRG); -+ } -+ -+ if (flow_type & (IRQ_TYPE_LEVEL_LOW | IRQ_TYPE_EDGE_FALLING)) { -+ data = readl(AMIC_BASE + INTLVL); -+ data |= 1 << irq; -+ writel(data, AMIC_BASE + INTLVL); -+ } -+ -+ if (flow_type & (IRQ_TYPE_LEVEL_HIGH | IRQ_TYPE_EDGE_RISING)) { -+ data = readl(AMIC_BASE + INTLVL); -+ data &= ~(1 << irq); -+ writel(data, AMIC_BASE + INTLVL); -+ } -+ spin_unlock(&amic_irq_lock); -+ return 0; -+} -+ -+static void amic_unmask_irq(unsigned int irq) -+{ -+ unsigned int data; -+ -+ spin_lock(&amic_irq_lock); -+ data = readl(AMIC_BASE + INTEN); -+ data |= 1 << irq; -+ writel(data, AMIC_BASE + INTEN); -+ data = readl(AMIC_BASE + INTEN); -+ spin_unlock(&amic_irq_lock); -+} -+ -+static int amic_set_affinity(unsigned int irq, const struct cpumask *dest) -+{ -+ int cnt = 0; -+ int cpu; -+ volatile unsigned int data; -+ volatile unsigned int dc, amic_irq; -+ -+ if (num_online_cpus() > 2) -+ return 0; -+ -+ spin_lock(&amic_irq_lock); -+ /* remap irq number for real controller */ -+ /* this may be needed in future */ -+ /* amic_irq = irq_remap(irq); */ -+ amic_irq = irq; -+ -+ /* change owner */ -+ data = readl(AMIC_BASE + CPUID0 + ((amic_irq >> 4) << 2)); -+ for_each_online_cpu(cpu) { -+ if (cpumask_test_cpu(cpu, dest)) { -+ data &= ~(0x3 << ((amic_irq & ~0x10) * 2)); -+ data |= cpu << ((amic_irq & ~0x10) * 2); -+ cnt++; -+ } -+ } -+ writel(data, AMIC_BASE + CPUID0 + ((amic_irq >> 4) << 2)); -+ -+ dc = readl(AMIC_BASE + CPUDC); -+ if (cnt == 2) /* set bit */ -+ writel((dc | (1 << amic_irq)), (AMIC_BASE + CPUDC)); -+ else /* clear bit */ -+ writel((dc & ~(1 << amic_irq)), (AMIC_BASE + CPUDC)); -+ -+ spin_unlock(&amic_irq_lock); -+ -+ DEBUG(0, 1, "en=%08x,status=%08x\n", readl(AMIC_BASE + INTEN), -+ readl(AMIC_BASE + INTSTA)); -+ -+ return 0; -+} -+ -+static struct irq_chip amic_chip = { -+ .name = "AMIC", -+ .ack = amic_ack_irq, -+ .mask = amic_mask_irq, -+ .unmask = amic_unmask_irq, -+ .set_affinity = amic_set_affinity, -+ .set_type = amic_set_type, -+}; -+ -+void __init amic_init(void) -+{ -+ int i, edge; -+ unsigned int temp = smp_processor_id(); -+ temp |= temp << 2; -+ temp |= temp << 4; -+ temp |= temp << 8; -+ temp |= temp << 16; -+ -+ writel(0x0, AMIC_BASE + INTEN); -+ writel(0x0, AMIC_BASE + CPUDC); -+ writel(temp, AMIC_BASE + CPUID0); -+ writel(temp, AMIC_BASE + CPUID1); -+ writel(0xffff, AMIC_BASE + IPISTA); -+ writel(0xffffffff, AMIC_BASE + INTSTA); -+ writel(0x11111111, AMIC_BASE + PRITY0); -+ writel(0x11111111, AMIC_BASE + PRITY1); -+ writel(0x11111111, AMIC_BASE + PRITY2); -+ writel(0x11111111, AMIC_BASE + PRITY3); -+ writel(DEFAULT_MODE, AMIC_BASE + INTTRG); -+ writel(~DEFAULT_LEVEL, AMIC_BASE + INTLVL); -+ printk("AMIC config %x %x\n", temp, readl(AMIC_BASE + CONFIG)); -+ -+ for (i = IRQ_BASE, edge = 1; i < IRQ_BASE + IRQ_TOTAL; i++, edge <<= 1) { -+ set_irq_chip(i, &amic_chip); -+ if (DEFAULT_MODE & edge) -+ set_irq_handler(i, handle_edge_irq); -+ else -+ set_irq_handler(i, handle_level_irq); -+ } -+ -+} -+ -+unsigned int get_IntSrc(void) -+{ -+ unsigned int irqsta, irq = 31; -+ -+ spin_lock(&amic_irq_lock); -+ irqsta = readl(AMIC_BASE + IPISTA); -+ if (irqsta != 0) -+ irqsta = 0; -+ else -+ irqsta = readl(AMIC_BASE + INTSTA); -+ spin_unlock(&amic_irq_lock); -+ -+ if (irqsta == 0) -+ return 32; -+ if (irqsta & 0x0000ffff) { -+ irq -= 16; -+ irqsta <<= 16; -+ } -+ if (irqsta & 0x00ff0000) { -+ irq -= 8; -+ irqsta <<= 8; -+ } -+ if (irqsta & 0x0f000000) { -+ irq -= 4; -+ irqsta <<= 4; -+ } -+ if (irqsta & 0x30000000) { -+ irq -= 2; -+ irqsta <<= 2; -+ } -+ if (irqsta & 0x40000000) { -+ irq -= 1; -+ } -+ return irq; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/dmad.c linux-3.4.113/arch/nds32/platforms/dmad.c ---- linux-3.4.113.orig/arch/nds32/platforms/dmad.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/dmad.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,3601 @@ -+/***************************************************************************** -+ * -+ * Copyright Andes Technology Corporation 2007-2008 -+ * All Rights Reserved. -+ * -+ * Revision History: -+ * -+ * Aug.21.2007 Created. -+ * Feb.23.2009 Porting to Linux 2.6. -+*****************************************************************************/ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+#define DMAD_AHB_MAX_CHANNELS DMAC_MAX_CHANNELS -+#else -+#define DMAD_AHB_MAX_CHANNELS 0 -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+#define DMAD_APB_MAX_CHANNELS APBBR_DMA_MAX_CHANNELS -+#else -+#define DMAD_APB_MAX_CHANNELS 0 -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+#define DMAD_DRB_POOL_SIZE 32 /* 128 */ -+ -+/* reg/io supplementals */ -+static inline void setbl(addr_t bit, addr_t reg) -+{ -+ outl(inl(reg) | (addr_t) ((addr_t) 1 << bit), reg); -+} -+ -+static inline void clrbl(addr_t bit, addr_t reg) -+{ -+ outl(inl(reg) & (~((addr_t) ((addr_t) 1 << bit))), reg); -+} -+ -+static inline addr_t getbl(addr_t bit, addr_t reg) -+{ -+ return inl(reg) & (addr_t) ((addr_t) 1 << bit); -+} -+ -+/******************************************************************************/ -+ -+enum DMAD_DRQ_FLAGS { -+ DMAD_DRQ_STATE_READY = 0x00000001, /* channel allocation status */ -+ DMAD_DRQ_STATE_ABORT = 0x00000002, /* abort drb alloc block-wait */ -+ DMAD_DRQ_DIR_A1_TO_A0 = 0x00000004, /* Transfer direction */ -+}; -+ -+#define DMAD_DRQ_DIR_MASK DMAD_DRQ_DIR_A1_TO_A0 -+ -+/* DMA request queue, one instance per channel */ -+typedef struct dmad_drq { -+ u32 state; /* enum DMAD_DRQ_STATE */ -+ -+ addr_t channel_base; /* register base address */ -+ addr_t enable_port; /* enable register */ -+ addr_t src_port; /* source address register */ -+ addr_t dst_port; /* dest address register */ -+ addr_t cyc_port; /* size(cycle) register */ -+ -+ u32 flags; /* enum DMAD_CHREQ_FLAGS */ -+ -+ spinlock_t drb_pool_lock; -+ dmad_drb *drb_pool; /* drb pool */ -+ -+ u32 fre_head; /* free list head */ -+ u32 fre_tail; /* free list tail */ -+ -+ u32 rdy_head; /* ready list head */ -+ u32 rdy_tail; /* ready list tail */ -+ -+ u32 sbt_head; /* submitted list head */ -+ u32 sbt_tail; /* submitted list tail */ -+ -+ u32 data_width; /* dma transfer data width */ -+ -+ struct completion drb_alloc_sync; -+ -+ /* client supplied callback function, executed in interrupt context -+ * client private data to be passed to data argument of completion_cb(). -+ */ -+ void (*completion_cb) (int channel, u16 status, void *data); -+ void *completion_data; -+ -+ /* ring-mode fields are valid for DMAD_FLAGS_RING_MODE */ -+ dma_addr_t ring_base; /* ring buffer base address */ -+ dma_addr_t ring_size; /* size (of data width) */ -+ addr_t ring_port; /* for setup/fetch hw_ptr */ -+ dmad_drb *ring_drb; -+ -+ addr_t dev_addr; /* device data port */ -+ -+ int periods; /* interrupts periods */ -+ dma_addr_t period_size; /* of dma data with */ -+ dma_addr_t period_bytes; /* Period size, in bytes */ -+ -+ /* ring_size - period_size * periods */ -+ dma_addr_t remnant_size; -+ -+ dma_addr_t sw_ptr; /* sw pointer */ -+ int sw_p_idx; /* current ring_ptr */ -+ dma_addr_t sw_p_off; /* offset to period base */ -+ -+} dmad_drq; -+ -+/* To shrink code size and improve performance, common channel registers -+ * are preload in drq struct at channel allocation time. One of the key -+ * dependency is the enable bit of both DMAC and APBDMA channel command -+ * registers. Please make sure hw design them at bit 0 of the command register -+ * in future evolvement. -+ */ -+#if (DMAC_CSR_CH_EN_BIT != APBBR_DMA_CHEN_BIT) -+#error "DMAC_CSR_CH_EN_BIT != APBBR_DMA_CHEN_BIT" -+#endif -+ -+#define DMAD_PORT_ENABLE_BIT APBBR_DMA_CHEN_BIT -+ -+static inline void dmad_enable_channel(dmad_drq * drq) -+{ -+ setbl(DMAD_PORT_ENABLE_BIT, drq->enable_port); -+} -+ -+static inline void dmad_disable_channel(dmad_drq * drq) -+{ -+ clrbl(DMAD_PORT_ENABLE_BIT, drq->enable_port); -+} -+ -+static inline addr_t dmad_is_channel_enabled(dmad_drq * drq) -+{ -+ return (addr_t) getbl(DMAD_PORT_ENABLE_BIT, drq->enable_port); -+} -+ -+/* AHB DMAC channel re-route table structure */ -+typedef struct _DMAD_AHB_CH_ROUTE { -+ u32 dev_reqn; /* device req/gnt number */ -+ addr_t clear_cr; /* routing control register address */ -+ addr_t route_cr; /* routing control register address */ -+} DMAD_AHB_CH_ROUTE; -+ -+#ifdef CONFIG_PLAT_AG102 -+#if 0 -+/* AHB DMAC channel re-route table. Indexed by AHB DMAC req/ack number. */ -+static DMAD_AHB_CH_ROUTE ahb_ch_route_table[] __attribute__ ((__unused__)) = { -+ /* all todo ... */ -+ -+ { -+ 0x00, DMAC_REQN_IDERX, DMAC_REQN_IDERX}, { -+ 0x01, DMAC_REQN_IDETX, DMAC_REQN_IDETX}, { -+ 0x02, DMAC_REQN_I2SAC97RX, DMAC_REQN_I2SAC97RX}, { -+ 0x03, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97TX}, { -+ 0x04, DMAC_REQN_UART2RX, DMAC_REQN_UART2RX}, { -+ 0x05, DMAC_REQN_UART2TX, DMAC_REQN_UART2TX}, { -+ 0x06, DMAC_REQN_UART1RX, DMAC_REQN_UART1RX}, { -+ 0x07, DMAC_REQN_UART1TX, DMAC_REQN_UART1TX}, { -+ 0x08, DMAC_REQN_SDC, DMAC_REQN_SDC}, { -+ 0x09, DMAC_REQN_CFC, DMAC_REQN_CFC}, { -+ 0x0a, DMAC_REQN_LPCREQ0, DMAC_REQN_LPCREQ0}, { -+ 0x0b, DMAC_REQN_LPCREQ1, DMAC_REQN_LPCREQ1}, { -+ 0x0c, DMAC_REQN_LPCREQ2, DMAC_REQN_LPCREQ2}, { -+ 0x0d, DMAC_REQN_LPCREQ3, DMAC_REQN_LPCREQ3}, { -+ 0x0e, 0, 0}, { -+0x0f, DMAC_REQN_LPCREQ5, DMAC_REQN_LPCREQ5},}; -+#endif -+#else /* CONFIG_PLAT_AG102 */ -+ -+/* AHB DMAC channel re-route table. Indexed by AHB DMAC req/ack number. */ -+static DMAD_AHB_CH_ROUTE ahb_ch_route_table[] = { -+ {0x00, 0, 0}, -+ {0x01, PMU_CFC_REQACK_CFG, PMU_CFC_REQACK_CFG}, -+ {0x02, PMU_SSP1_REQACK_CFG, PMU_SSP1_REQACK_CFG}, -+ {0x03, PMU_UART1RX_REQACK_CFG, PMU_UART1TX_REQACK_CFG}, -+ {0x04, PMU_UART1TX_REQACK_CFG, PMU_UART1RX_REQACK_CFG}, -+ {0x05, PMU_UART2RX_REQACK_CFG, PMU_UART2TX_REQACK_CFG}, -+ {0x06, PMU_UART2TX_REQACK_CFG, PMU_UART2RX_REQACK_CFG}, -+ {0x07, PMU_SDC_REQACK_CFG, PMU_SDC_REQACK_CFG}, -+ {0x08, PMU_I2SAC97RX_REQACK_CFG, PMU_I2SAC97TX_REQACK_CFG}, -+ {0x09, 0, 0}, -+ {0x0a, PMU_I2SAC97TX_REQACK_CFG, PMU_I2SAC97RX_REQACK_CFG}, -+ {0x0b, PMU_USB_REQACK_CFG, PMU_USB_REQACK_CFG}, -+ {0x0c, 0, 0}, -+ {0x0d, 0, 0}, -+ {0x0e, PMU_EXT0_REQACK_CFG, PMU_EXT0_REQACK_CFG}, -+ {0x0f, PMU_EXT1_REQACK_CFG, PMU_EXT1_REQACK_CFG}, -+}; -+ -+#endif /* CONFIG_PLAT_AG102 */ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ -+/* system irq number (per channel, ahb) */ -+static const unsigned int ahb_irqs[DMAD_AHB_MAX_CHANNELS] = { -+ DMAC_FTDMAC020_0_IRQ0, -+ DMAC_FTDMAC020_0_IRQ1, -+ DMAC_FTDMAC020_0_IRQ2, -+ DMAC_FTDMAC020_0_IRQ3, -+ DMAC_FTDMAC020_0_IRQ4, -+ DMAC_FTDMAC020_0_IRQ5, -+ DMAC_FTDMAC020_0_IRQ6, -+ DMAC_FTDMAC020_0_IRQ7, -+}; -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+/* APB Bridge DMA request number re-route table */ -+typedef struct _DMAD_APB_REQN_ROUTE { -+ u32 apb_reqn; /* APB device req/gnt number */ -+ u32 ahb_reqn_tx; /* AHB DMAC req/ack number (tx) */ -+ u32 ahb_reqn_rx; /* AHB DMAC req/ack number (rx) */ -+ u32 bus_sel; /* APBBR_ADDRSEL_APB(0) or APBBR_ADDRSEL_AHB(1) */ -+} DMAD_APB_REQN_ROUTE; -+ -+#ifdef CONFIG_PLAT_AG102 -+ -+/* APB Bridge DMA request number re-route table. Indexed by APB DMA req/gnt -+ * number. */ -+static DMAD_APB_REQN_ROUTE apb_reqn_route_table[] = { -+ {0x00, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x01, DMAC_REQN_CFC, DMAC_REQN_CFC, APBBR_ADDRSEL_APB}, -+ {0x02, 0x00, 0x00, APBBR_ADDRSEL_APB}, -+ {0x03, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x04, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ //MOD by river 2010.10.20 -+ {0x05, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ //End MOD by river 2010.10.20 -+ {0x06, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, -+ {0x07, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ //MOD by river 2010.10.20 -+ {0x08, DMAC_REQN_SDC, DMAC_REQN_SDC, APBBR_ADDRSEL_APB}, -+ //End MOD by river 2010.10.20 -+ {0x09, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0a, DMAC_REQN_UART2TX, DMAC_REQN_UART2RX, APBBR_ADDRSEL_APB}, -+ {0x0b, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0c, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0d, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, -+ {0x0e, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0f, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+}; -+ -+#else /* CONFIG_PLAT_AG102 */ -+ -+/* APB Bridge DMA request number re-route table. Indexed by APB DMA req/gnt -+ * number. */ -+static DMAD_APB_REQN_ROUTE apb_reqn_route_table[] = { -+ {0x00, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x01, DMAC_REQN_CFC, DMAC_REQN_CFC, APBBR_ADDRSEL_APB}, -+ {0x02, DMAC_REQN_SSP, DMAC_REQN_SSP, APBBR_ADDRSEL_APB}, -+ {0x03, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x04, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x05, DMAC_REQN_SDC, DMAC_REQN_SDC, APBBR_ADDRSEL_APB}, -+ {0x06, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, -+/* for amerald -+ { 0x07, 0x00, 0x00, APBBR_ADDRSEL_AHB },*/ -+ {0x07, APBBR_REQN_SDC_AMERALD, APBBR_REQN_SDC_AMERALD, -+ APBBR_ADDRSEL_AHB}, -+/* for amerald ac97 -+ { 0x08, 0x00, 0x00, APBBR_ADDRSEL_AHB }, */ -+ {0x08, APBBR_REQN_I2SAC97TX_AMERALD, APBBR_REQN_I2SAC97TX_AMERALD, -+ APBBR_ADDRSEL_APB}, -+ {0x09, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0a, DMAC_REQN_UART2TX, DMAC_REQN_UART2RX, APBBR_ADDRSEL_APB}, -+ {0x0b, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0c, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0d, DMAC_REQN_I2SAC97TX, DMAC_REQN_I2SAC97RX, APBBR_ADDRSEL_APB}, -+ {0x0e, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+ {0x0f, 0x00, 0x00, APBBR_ADDRSEL_AHB}, -+}; -+ -+#endif /* CONFIG_PLAT_AG102 */ -+ -+/* system irq number (per channel, apb) */ -+static const unsigned int apb_irqs[DMAD_APB_MAX_CHANNELS] = { -+ APBBRG_FTAPBBRG020S_0_IRQ0, -+ APBBRG_FTAPBBRG020S_0_IRQ1, -+ APBBRG_FTAPBBRG020S_0_IRQ2, -+ APBBRG_FTAPBBRG020S_0_IRQ3, -+}; -+ -+#endif -+ -+/* Driver data structure, one instance per system */ -+typedef struct DMAD_DATA_STRUCT { -+ /* Driver data initialization flag */ -+ -+ /* DMA queue pool access control object */ -+ spinlock_t drq_pool_lock; -+ -+ /* DMA queue base address, to ease alloc/free flow */ -+ dmad_drq *drq_pool; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ /* DMA queue for AHB DMA channels */ -+ dmad_drq *ahb_drq_pool; -+#endif -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ /* DMA queue for APB DMA channels */ -+ dmad_drq *apb_drq_pool; -+#endif -+ -+} DMAD_DATA; -+ -+/* Driver data structure instance, one instance per system */ -+static DMAD_DATA dmad __attribute__ ((aligned(4))) = { -+ .drq_pool_lock = __SPIN_LOCK_UNLOCKED(dmad.drq_pool_lock), -+// .drq_pool_lock = SPIN_LOCK_UNLOCKED, -+ .drq_pool = 0, -+#ifdef CONFIG_PLATFORM_AHBDMA -+ .ahb_drq_pool = 0, -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ .apb_drq_pool = 0, -+#endif -+}; -+ -+/** -+ * dmad_next_drb - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @node : [in] The node number to lookup its next node -+ * @drb : [out] The drb next to the "node" node number -+ * -+ * Lookup next DRB of the specified node number. "drb" is null if reaches end -+ * of the list. -+ */ -+static inline void dmad_next_drb(dmad_drb * drb_pool, u32 node, dmad_drb ** drb) -+{ -+ if (likely(drb_pool[node].next != 0)) -+ *drb = &drb_pool[drb_pool[node].next]; -+ else -+ *drb = 0; -+} -+ -+/** -+ * dmad_prev_drb - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @node : [in] The node number to lookup its previous node -+ * @drb : [out] The drb previous to the "node" node number -+ * -+ * Lookup previous DRB of the specified node number. "drb" is null if reaches -+ * head-end of the list. -+ */ -+static inline void dmad_prev_drb(dmad_drb * drb_pool, u32 node, dmad_drb ** drb) -+{ -+ if (unlikely(drb_pool[node].prev != 0)) -+ *drb = &drb_pool[drb_pool[node].prev]; -+ else -+ *drb = 0; -+} -+ -+/** -+ * dmad_detach_node - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @node : [in] The node to be dettached from the queue -+ * -+ * Detached a DRB specified by the node number from the queue. The head and -+ * tail records will be updated accordingly. -+ */ -+static inline void dmad_detach_node(dmad_drb * drb_pool, -+ u32 * head, u32 * tail, u32 node) -+{ -+ if (likely(drb_pool[node].prev != 0)) { -+ /* prev->next = this->next (= 0, if this is a tail) */ -+ drb_pool[drb_pool[node].prev].next = drb_pool[node].next; -+ } else { -+ /* this node is head, move head to next node -+ * (= 0, if this is the only one node) */ -+ *head = drb_pool[node].next; -+ } -+ -+ if (unlikely(drb_pool[node].next != 0)) { -+ /* next->prev = this->prev (= 0, if this is a head) */ -+ drb_pool[drb_pool[node].next].prev = drb_pool[node].prev; -+ } else { -+ /* this node is tail, move tail to previous node -+ * (= 0, if this is the only one node) */ -+ *tail = drb_pool[node].prev; -+ } -+ -+ drb_pool[node].prev = drb_pool[node].next = 0; -+} -+ -+/** -+ * dmad_detach_head - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @drb : [out] The detached head node; null if the queue is empty -+ * -+ * Detached a DRB from the head of the queue. The head and tail records will -+ * be updated accordingly. -+ */ -+static inline void dmad_detach_head(dmad_drb * drb_pool, -+ u32 * head, u32 * tail, dmad_drb ** drb) -+{ -+ if (unlikely(*head == 0)) { -+ *drb = NULL; -+ return; -+ } -+ -+ *drb = &drb_pool[*head]; -+ -+ if (likely((*drb)->next != 0)) { -+ /* next->prev = this->prev (= 0, if this is a head) */ -+ drb_pool[(*drb)->next].prev = 0; -+ -+ /* prev->next = this->next (do nothing, if this is a head) */ -+ -+ /* head = this->next */ -+ *head = (*drb)->next; -+ } else { -+ /* head = tail = 0 */ -+ *head = 0; -+ *tail = 0; -+ } -+ -+ /* this->prev = this->next = 0 (do nothing, if save code size) */ -+ (*drb)->prev = (*drb)->next = 0; -+} -+ -+/** -+ * dmad_get_head - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @drb : [out] The head node; null if the queue is empty -+ * -+ * Get a DRB from the head of the queue. The head and tail records remain -+ * unchanged. -+ */ -+static inline void dmad_get_head(dmad_drb * drb_pool, const u32 * head, -+ const u32 * tail, dmad_drb ** drb) -+{ -+ if (unlikely(*head == 0)) { -+ *drb = NULL; -+ return; -+ } -+ -+ *drb = &drb_pool[*head]; -+} -+ -+/** -+ * dmad_detach_tail - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @drb : [out] The tail node; null if the queue is empty -+ * -+ * Detached a DRB from the head of the queue. The head and tail records will -+ * be updated accordingly. -+ */ -+static inline void dmad_detach_tail(dmad_drb * drb_pool, -+ u32 * head, u32 * tail, dmad_drb ** drb) -+{ -+ if (unlikely(*tail == 0)) { -+ *drb = NULL; -+ return; -+ } -+ -+ *drb = &drb_pool[*tail]; -+ -+ if (likely((*drb)->prev != 0)) { -+ /* prev->next = this->next (= 0, if this is a tail) */ -+ drb_pool[(*drb)->prev].next = 0; -+ -+ /* next->prev = this->prev (do nothing, if this is a tail) */ -+ -+ /* tail = this->prev */ -+ *tail = (*drb)->prev; -+ } else { -+ /* head = tail = 0 */ -+ *head = 0; -+ *tail = 0; -+ } -+ -+ /* this->next = this->prev = 0 (do nothing, if save code size) */ -+ (*drb)->prev = (*drb)->next = 0; -+} -+ -+/** -+ * dmad_get_tail - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @drb : [out] The tail node; null if the queue is empty -+ * -+ * Get a DRB from the tail of the queue. The head and tail records remain -+ * unchanged. -+ */ -+static inline void dmad_get_tail(dmad_drb * drb_pool, -+ u32 * head, u32 * tail, dmad_drb ** drb) -+{ -+ if (unlikely(*tail == 0)) { -+ *drb = NULL; -+ return; -+ } -+ -+ *drb = &drb_pool[*tail]; -+} -+ -+/** -+ * dmad_attach_head - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @node : [in] The node to be attached -+ * -+ * Attach a DRB node to the head of the queue. The head and tail records will -+ * be updated accordingly. -+ */ -+static inline void dmad_attach_head(dmad_drb * drb_pool, -+ u32 * head, u32 * tail, u32 node) -+{ -+ if (likely(*head != 0)) { -+ /* head->prev = this */ -+ drb_pool[*head].prev = node; -+ -+ /* this->next = head */ -+ drb_pool[node].next = *head; -+ /* this->prev = 0 */ -+ drb_pool[node].prev = 0; -+ -+ /* head = node */ -+ *head = node; -+ } else { -+ /* head = tail = node */ -+ *head = *tail = node; -+ drb_pool[node].prev = drb_pool[node].next = 0; -+ } -+} -+ -+/** -+ * dmad_attach_head - static function -+ * @drb_pool : [in] The raw DRB pool of a DMA channel -+ * @head : [in/out] Reference to the head node number -+ * @tail : [in/out] Reference to the tail node number -+ * @node : [in] The node to be attached -+ * -+ * Attach a DRB node to the tail of the queue. The head and tail records will -+ * be updated accordingly. -+ */ -+static inline void dmad_attach_tail(dmad_drb * drb_pool, -+ u32 * head, u32 * tail, u32 node) -+{ -+ if (likely(*tail != 0)) { -+ /* tail->next = this */ -+ drb_pool[*tail].next = node; -+ -+ /* this->prev = tail */ -+ drb_pool[node].prev = *tail; -+ /* this->next = 0 */ -+ drb_pool[node].next = 0; -+ -+ /* tail = node */ -+ *tail = node; -+ } else { -+ /* head = tail = node */ -+ *head = *tail = node; -+ drb_pool[node].prev = drb_pool[node].next = 0; -+ } -+} -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ -+/** -+ * dmad_ahb_isr - AHB DMA interrupt service routine -+ * -+ * @irq : [in] The irq number -+ * @dev_id : [in] The identifier to identify the asserted channel -+ * -+ * This is the ISR that services all AHB DMA channels. -+ */ -+static irqreturn_t dmad_ahb_isr(int irq, void *dev_id) -+{ -+ dmad_drq *drq; -+ dmad_drb *drb, *drb_iter; -+ u32 channel = ((u32) dev_id) - 1; -+ u8 tc_int = 0; -+ u8 err_int = 0; -+ u8 abt_int = 0; -+ u8 cpl_events = 1; -+ -+ dmad_dbg("%s() >> channel(%d)\n", __func__, channel); -+ -+ if (channel >= DMAD_AHB_MAX_CHANNELS) { -+ dmad_err("%s() invlaid channel number: %d!\n", -+ __func__, channel); -+ return IRQ_HANDLED; -+ } -+ -+ /* Fetch channel's DRQ struct (DMA Request Queue) */ -+ drq = (dmad_drq *) & dmad.ahb_drq_pool[channel]; -+ -+ /* Check DMA status register to get channel number */ -+ if (likely(getbl(channel, DMAC_INT_TC))) { -+ -+ /* Mark as TC int */ -+ tc_int = 1; -+ -+ /* DMAC INT TC status clear */ -+ setbl(channel, DMAC_INT_TC_CLR); -+ -+ } else if (getbl(channel + DMAC_INT_ERR_SHIFT, DMAC_INT_ERRABT)) { -+ -+ /* Mark as ERR int */ -+ err_int = 1; -+ -+ /* DMAC INT ERR status clear */ -+ setbl(channel + DMAC_INT_ERR_CLR_SHIFT, DMAC_INT_ERRABT_CLR); -+ -+ } else if (getbl(channel + DMAC_INT_ABT_SHIFT, DMAC_INT_ERRABT)) { -+ -+ /* Mark as ABT int */ -+ abt_int = 1; -+ -+ /* DMAC INT ABT status clear */ -+ setbl(channel + DMAC_INT_ABT_CLR_SHIFT, DMAC_INT_ERRABT_CLR); -+ -+ } else { -+ -+ dmad_err("%s() possible false-fired ahb dma int," -+ "channel %d status-reg: tc(0x%08x) arrabt(0x%08x)\n", -+ __func__, channel, -+ inl(DMAC_INT_TC), inl(DMAC_INT_ERRABT_CLR)); -+ -+ /* Stop DMA channel (make sure the channel will be stopped) */ -+ clrbl(DMAC_CSR_CH_EN_BIT, drq->channel_base + DMAC_CSR_OFFSET); -+ -+ return IRQ_HANDLED; -+ } -+ -+ /* DMAC -+ * Stop DMA channel temporarily */ -+ dmad_disable_channel(drq); -+ -+ spin_lock(&drq->drb_pool_lock); -+ -+ /* Lookup/detach latest submitted DRB (DMA Request Block) from -+ * the DRQ (DMA Request Queue), so ISR could kick off next DRB */ -+ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); -+ if (drb == NULL) { -+ spin_unlock(&drq->drb_pool_lock); -+ /* submitted list could be empty if client cancel all requests -+ * of the channel. */ -+ return IRQ_HANDLED; -+ } -+ -+ /* release blocking of drb-allocation, if any ... */ -+ if (unlikely((drq->fre_head == 0) && -+ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK))) { -+ complete_all(&drq->drb_alloc_sync); -+ } -+ -+ /* Process DRBs according to interrupt reason */ -+ if (tc_int) { -+ -+ dmad_dbg("dma finish\n"); -+ -+ dmad_dbg("finish drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x)\n", -+ drb->node, (u32) drb, drb->src_addr, -+ drb->dst_addr, drb->req_cycle); -+ -+ if (drb->req_cycle == 0) -+ cpl_events = 0; -+ -+ // Mark DRB state as completed -+ drb->state = DMAD_DRB_STATE_COMPLETED; -+ if (cpl_events && drb->sync) -+ complete_all(drb->sync); -+ -+ dmad_attach_tail(drq->drb_pool, &drq->fre_head, -+ &drq->fre_tail, drb->node); -+ -+ // Check whether there are pending requests in the DRQ -+ if (drq->sbt_head != 0) { -+ -+ // Lookup next DRB (DMA Request Block) -+ drb_iter = &drq->drb_pool[drq->sbt_head]; -+ -+ dmad_dbg("exec drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x)\n", -+ drb_iter->node, (u32) drb_iter, -+ drb_iter->src_addr, drb_iter->dst_addr, -+ drb_iter->req_cycle); -+ -+ // Kick-off DMA for next DRB -+ // - Source and destination address -+ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { -+ outl(drb_iter->addr1, drq->src_port); -+ outl(drb_iter->addr0, drq->dst_port); -+ } else { -+ outl(drb_iter->addr0, drq->src_port); -+ outl(drb_iter->addr1, drq->dst_port); -+ } -+ -+ /* - Transfer size (in units of source width) */ -+ outl(drb_iter->req_cycle, drq->cyc_port); -+ -+ /* Kick off next request */ -+ dmad_enable_channel(drq); -+ -+ drb_iter->state = DMAD_DRB_STATE_EXECUTED; -+ -+ } else { -+ /* No pending requests, keep the DMA channel stopped */ -+ } -+ -+ } else { -+ -+ dmad_err("%s() ahb dma channel %d error!\n", __func__, channel); -+ -+ /* Zero out src, dst, and size */ -+ outl(0, drq->src_port); -+ outl(0, drq->dst_port); -+ outl(0, drq->cyc_port); -+ -+ /* Remove all pending requests in the queue */ -+ drb_iter = drb; -+ while (drb_iter) { -+ -+ dmad_err("abort drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x)\n", -+ drb_iter->node, (u32) drb_iter, -+ drb_iter->src_addr, drb_iter->dst_addr, -+ drb_iter->req_cycle); -+ -+ if (drb_iter->req_cycle == 0) -+ cpl_events = 0; -+ -+ /* Mark DRB state as abort */ -+ drb_iter->state = DMAD_DRB_STATE_ABORT; -+ -+ if (cpl_events && drb_iter->sync) -+ complete_all(drb_iter->sync); -+ -+ dmad_attach_tail(drq->drb_pool, &drq->fre_head, -+ &drq->fre_tail, drb_iter->node); -+ -+ /* Detach next submitted DRB (DMA Request Block) -+ * from the DRQ (DMA Request Queue) */ -+ dmad_detach_head(drq->drb_pool, &drq->sbt_head, -+ &drq->sbt_tail, &drb_iter); -+ } -+ } -+ -+ spin_unlock(&drq->drb_pool_lock); -+ -+ /* dispatch interrupt-context level callbacks */ -+ if (cpl_events && drq->completion_cb) { -+ /* signal DMA driver that new node is available */ -+ drq->completion_cb(channel, tc_int, drq->completion_data); -+ } -+ -+ dmad_dbg("%s() <<\n", __func__); -+ -+ return IRQ_HANDLED; -+} -+ -+/** -+ * dmad_ahb_config_dir - prepare command reg according to tx direction -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @channel_cmds : [out] Reference to array of command words to be prepared with -+ * @return : none -+ * -+ * Prepare command registers according to transfer direction ... -+ * channel_cmd[0] DMAC_CSR -+ * channel_cmd[1] DMAC_CFG -+ * -+ * This function only serves as local helper. No protection wrappers. -+ */ -+static void dmad_ahb_config_dir(dmad_chreq * ch_req, addr_t * channel_cmds) -+{ -+ dmad_drq *drq = (dmad_drq *) ch_req->drq; -+ dmad_ahb_chreq *ahb_req = (dmad_ahb_chreq *) (&ch_req->ahb_req); -+/* for amerald */ -+ u32 reqn0, reqn1; -+ dmad_dbg("%s() channel_cmds(0x%08x, 0x%08x)\n", -+ __func__, channel_cmds[0], channel_cmds[1]); -+/* for amerald */ -+ if ((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) { -+ reqn0 = ahb_req->addr0_reqn; -+ reqn1 = ahb_req->addr1_reqn; -+ } else { -+ reqn0 = ch_req->channel; -+ reqn1 = ch_req->channel; -+ } -+ channel_cmds[0] &= ~(addr_t) -+ (DMAC_CSR_SRC_WIDTH_MASK | DMAC_CSR_SRCAD_CTL_MASK | -+ DMAC_CSR_DST_WIDTH_MASK | DMAC_CSR_DSTAD_CTL_MASK | -+ DMAC_CSR_MODE_MASK); -+ channel_cmds[1] &= ~(addr_t) -+ (DMAC_CFG_INT_SRC_RS_MASK | DMAC_CFG_INT_SRC_HE_MASK | -+ DMAC_CFG_INT_DST_RS_MASK | DMAC_CFG_INT_DST_HE_MASK); -+ -+ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ -+ if (ahb_req->tx_dir == 0) { -+ -+ dmad_dbg("%s() addr0 --> addr1\n", __func__); -+ -+ /* - Channel CSR -+ * DST_SEL : 0 (Master 0) -+ * SRC_SEL : 0 (Master 0) -+ * DSTAD_CTL : ahb_req->dst_ctrl -+ * SRCAD_CTL : ahb_req->src_ctrl -+ * MODE : 0 (normal) -+ * DST_WIDTH : ahb_req->dst_width -+ * SRC_WIDTH : ahb_req->src_width -+ * SRC_SIZE : 0 (burst size = 1 byte) -+ */ -+ channel_cmds[0] |= -+ (((ahb_req->addr0_width << DMAC_CSR_SRC_WIDTH_SHIFT) & -+ DMAC_CSR_SRC_WIDTH_MASK) | -+ ((ahb_req->addr0_ctrl << DMAC_CSR_SRCAD_CTL_SHIFT) & -+ DMAC_CSR_SRCAD_CTL_MASK) | -+ ((ahb_req->addr1_width << DMAC_CSR_DST_WIDTH_SHIFT) & -+ DMAC_CSR_DST_WIDTH_MASK) | -+ ((ahb_req->addr1_ctrl << DMAC_CSR_DSTAD_CTL_SHIFT) & -+ DMAC_CSR_DSTAD_CTL_MASK)); -+ -+ /* - Channel CFG -+ * SRC_RS : channel number (not reqn) -+ * SRC_HE : 0 if memory, 1 if device -+ * DST_RS : channel number (not reqn) -+ * DST_HE : 0 if memory, 1 if device -+ */ -+ if (likely(ahb_req->hw_handshake != 0)) { -+ /* Channel CSR - Enable HW-handshake mode */ -+ channel_cmds[0] |= DMAC_CSR_MODE_MASK; -+ -+ /* Channel CFG - Device REQN and HW-handshake mode */ -+#ifdef CONFIG_PLAT_AG102 -+ /* AG102 fixes this bug */ -+ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | -+ ((ahb_req->addr0_reqn << -+ DMAC_CFG_INT_SRC_RS_SHIFT) -+ & -+ DMAC_CFG_INT_SRC_RS_MASK)); -+ } -+ -+ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | -+ ((ahb_req->addr1_reqn << -+ DMAC_CFG_INT_DST_RS_SHIFT) -+ & -+ DMAC_CFG_INT_DST_RS_MASK)); -+ } -+#else -+ /* AG101/XC5 bug */ -+/* for amerald */ -+ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | -+ ((reqn0 << -+ DMAC_CFG_INT_SRC_RS_SHIFT) -+ & -+ DMAC_CFG_INT_SRC_RS_MASK)); -+ } -+ -+ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | -+ ((reqn1 << -+ DMAC_CFG_INT_DST_RS_SHIFT) -+ & -+ DMAC_CFG_INT_DST_RS_MASK)); -+ } -+#endif -+ } -+ -+ /* update source data width for faster cycle/byte size conversion */ -+ drq->data_width = ahb_req->addr0_width; -+ -+ /* remember channel transfer direction */ -+ drq->flags &= ~(addr_t) DMAD_DRQ_DIR_A1_TO_A0; -+ -+ } else { -+ -+ dmad_dbg("%s() addr0 <-- addr1\n", __func__); -+ -+ /* - Channel CSR -+ * DST_SEL : 0 (Master 0) -+ * SRC_SEL : 0 (Master 0) -+ * DSTAD_CTL : ahb_req->dst_ctrl -+ * SRCAD_CTL : ahb_req->src_ctrl -+ * MODE : 0 (normal) -+ * DST_WIDTH : ahb_req->dst_width -+ * SRC_WIDTH : ahb_req->src_width -+ * SRC_SIZE : 0 (burst size = 1 byte) -+ */ -+ channel_cmds[0] |= -+ (((ahb_req->addr1_width << DMAC_CSR_SRC_WIDTH_SHIFT) & -+ DMAC_CSR_SRC_WIDTH_MASK) | -+ ((ahb_req->addr1_ctrl << DMAC_CSR_SRCAD_CTL_SHIFT) & -+ DMAC_CSR_SRCAD_CTL_MASK) | -+ ((ahb_req->addr0_width << DMAC_CSR_DST_WIDTH_SHIFT) & -+ DMAC_CSR_DST_WIDTH_MASK) | -+ ((ahb_req->addr0_ctrl << DMAC_CSR_DSTAD_CTL_SHIFT) & -+ DMAC_CSR_DSTAD_CTL_MASK)); -+ -+ /* - Channel CFG -+ * SRC_RS : channel number (not reqn) -+ * SRC_HE : 0 if memory, 1 if device -+ * DST_RS : channel number (not reqn) -+ * DST_HE : 0 if memory, 1 if device -+ */ -+ if (likely(ahb_req->hw_handshake != 0)) { -+ /* Channel CSR - Enable HW-handshake mode */ -+ channel_cmds[0] |= DMAC_CSR_MODE_MASK; -+ -+ /* Channel CFG - Device REQN and HW-handshake mode */ -+#ifdef CONFIG_PLAT_AG102 -+ /* AG102 fixes this bug */ -+ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | -+ ((ahb_req->addr1_reqn << -+ DMAC_CFG_INT_SRC_RS_SHIFT) -+ & -+ DMAC_CFG_INT_SRC_RS_MASK)); -+ } -+ -+ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | -+ ((ahb_req->addr0_reqn << -+ DMAC_CFG_INT_DST_RS_SHIFT) -+ & -+ DMAC_CFG_INT_DST_RS_MASK)); -+ } -+#else -+ /* AG101/XC5 bug */ -+/* for amerald */ -+ if (ahb_req->addr1_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_SRC_HE_MASK | -+ ((reqn1 << -+ DMAC_CFG_INT_SRC_RS_SHIFT) -+ & -+ DMAC_CFG_INT_SRC_RS_MASK)); -+ } -+ -+ if (ahb_req->addr0_reqn != DMAC_REQN_NONE) { -+ channel_cmds[1] |= (DMAC_CFG_INT_DST_HE_MASK | -+ ((reqn0 << -+ DMAC_CFG_INT_DST_RS_SHIFT) -+ & -+ DMAC_CFG_INT_DST_RS_MASK)); -+ } -+#endif -+ } -+ -+ /* source data width */ -+ drq->data_width = ahb_req->addr1_width; -+ -+ /* remember channel transfer direction */ -+ drq->flags |= (addr_t) DMAD_DRQ_DIR_A1_TO_A0; -+ } -+ -+ dmad_dbg("%s() channel_cmds(0x%08x, 0x%08x)\n", -+ __func__, channel_cmds[0], channel_cmds[1]); -+} -+ -+/** -+ * dmad_ahb_init - initialize a ahb dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * Register AHB DMA ISR and performs hw initialization for the given DMA -+ * channel. -+ */ -+static int dmad_ahb_init(dmad_chreq * ch_req) -+{ -+ int err = 0; -+ dmad_drq *drq = (dmad_drq *) ch_req->drq; -+ dmad_ahb_chreq *ahb_req = (dmad_ahb_chreq *) (&ch_req->ahb_req); -+ u32 channel = (u32) ch_req->channel; -+ addr_t channel_base = drq->channel_base; -+ addr_t channel_cmds[2]; // [0] DMAC_CSR; [1] DMAC_CFG -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ /* register interrupt handler */ -+ err = request_irq(ahb_irqs[channel], dmad_ahb_isr, 0, -+ "AHB_DMA", (void *)(channel + 1)); -+ if (unlikely(err != 0)) { -+ dmad_err("unable to request IRQ %d for AHB DMA " -+ "(error %d)\n", ahb_irqs[channel], err); -+ free_irq(ahb_irqs[channel], (void *)(channel + 1)); -+ return err; -+ } -+ -+ spin_lock_irqsave(&dmad.drq_pool_lock, lock_flags); -+ -+ /********************************************************** -+ * Following code require _safe_exit return path -+ */ -+ -+#ifdef CONFIG_PLAT_AG102 -+ /* PCU -+ * -+ * Add by Dennis 2011.03.09 -+ * set 0 to dma selection register to using AHB -+ * DMA. -+ */ -+ if (ahb_req->dst_reqn == ahb_req->src_reqn) { -+ dmad_err -+ ("[dmad] invalid source reqn(%d) or destination reqn(%d)\n", -+ ahb_req->src_reqn, ahb_req->dst_reqn); -+ err = -EBADR; -+ goto _safe_exit; -+ } -+ outl(0, PCU_DMA_SEL); -+#else /* CONFIG_PLAT_AG102 */ -+ -+ /* PMU -+ * -+ * Route APB device DMA to an AHB DMAC channel and specify the channel -+ * number. (connection status could be read back from PMU_AHBDMA_REQACK -+ * register) -+ * -+ * Note: Only one device is routed per AHB DMA channel, the other target -+ * should be either (1) the same device (same reqn), or (2) the AHB -+ * device (reqn = 0). -+ */ -+ -+ if (ahb_req->dst_reqn != DMAC_REQN_NONE) { -+ // DMA transfer to device -+ if ((ahb_req->dst_reqn > DMAC_REQN_MAX) || -+ (ahb_ch_route_table[ahb_req->dst_reqn].route_cr == 0)) { -+ dmad_err("Invalid destination reqn(%d) " -+ "or route_cr(0x%08x)\n", ahb_req->dst_reqn, -+ (u32) ahb_ch_route_table[ahb_req->dst_reqn]. -+ route_cr); -+ err = -EBADR; -+ goto _safe_exit; -+ } -+ -+ outl(0, ahb_ch_route_table[ahb_req->dst_reqn].clear_cr); -+ outl(PMU_DMACUSED_MASK | ((channel << PMU_CHANNEL_SHIFT) & -+ PMU_CHANNEL_MASK), -+ ahb_ch_route_table[ahb_req->dst_reqn].route_cr); -+ -+ } else if (ahb_req->src_reqn != DMAC_REQN_NONE) { -+ -+ // DMA transfer from device -+ if ((ahb_req->src_reqn > DMAC_REQN_MAX) || -+ (ahb_ch_route_table[ahb_req->src_reqn].route_cr == 0)) { -+ dmad_err("Invalid source reqn(%d) or " -+ "route_cr(0x%08x)\n", ahb_req->src_reqn, -+ (u32) ahb_ch_route_table[ahb_req->src_reqn]. -+ route_cr); -+ err = -EBADR; -+ goto _safe_exit; -+ } -+ -+ outl(0, ahb_ch_route_table[ahb_req->src_reqn].clear_cr); -+ outl(PMU_DMACUSED_MASK | ((channel << PMU_CHANNEL_SHIFT) & -+ PMU_CHANNEL_MASK), -+ ahb_ch_route_table[ahb_req->src_reqn].route_cr); -+ } -+#endif /* CONFIG_PLAT_AG102 */ -+ -+ /* DMAC (Controller Setting) */ -+ -+ /* - INT TC/ERR/ABT status clear */ -+ setbl(channel, DMAC_INT_TC_CLR); -+ setbl(channel + DMAC_INT_ERR_CLR_SHIFT, DMAC_INT_ERRABT_CLR); -+ setbl(channel + DMAC_INT_ABT_CLR_SHIFT, DMAC_INT_ERRABT_CLR); -+ -+ // - CSR (enable DMAC, set M0 & M1 default to little endian) -+ outl(DMAC_DMACEN_MASK | -+ ((DMAC_ENDIAN_LITTLE << DMAC_M0ENDIAN_BIT) & DMAC_M0ENDIAN_MASK) | -+ ((DMAC_ENDIAN_LITTLE << DMAC_M1ENDIAN_BIT) & DMAC_M1ENDIAN_MASK), -+ DMAC_CSR); -+ -+ /* DMAC (Channel-Specific Setting) */ -+ /* - SYNC */ -+ if (ahb_req->sync) -+ setbl(channel, DMAC_SYNC); -+ else -+ clrbl(channel, DMAC_SYNC); -+ -+ /* - Channel CSR -+ * CH_EN : 0 (disable) -+ * DST_SEL : 0 (Master 0) -+ * SRC_SEL : 0 (Master 0) -+ * DSTAD_CTL : ahb_req->dst_ctrl -+ * SRCAD_CTL : ahb_req->src_ctrl -+ * MODE : 0 (normal) -+ * DST_WIDTH : ahb_req->dst_width -+ * SRC_WIDTH : ahb_req->src_width -+ * ABT : 0 (not abort) -+ * SRC_SIZE : 0 (burst size = 1 byte) -+ * PROT1 : 0 (user mode) -+ * PROT2 : 0 (bot bufferable) -+ * PROT3 : 0 (not cacheable) -+ * CHPRI : ahb_req->priority -+ * DMA_FF_TH : 0 (FIA320 only, threshold = 1) -+ * TC_MSK : 0 (TC counter status enable) -+ */ -+ channel_cmds[0] = (ahb_req->priority << DMAC_CSR_CHPRI_SHIFT) & -+ DMAC_CSR_CHPRI_MASK; -+ channel_cmds[0] |= (ahb_req->burst_size << DMAC_CSR_SRC_SIZE_SHIFT) & -+ DMAC_CSR_SRC_SIZE_MASK; -+ -+ // - Channel CFG -+ // INT_TC_MSK : 0 (enable TC int) -+ // INT_ERR_MSK : 0 (enable ERR int) -+ // INT_ABT_MSK : 0 (enable ABT int) -+ // SRC_RS : 0 -+ // SRC_HE : 0 -+ // BUSY : r/o -+ // DST_RS : 0 -+ // DST_HE : 0 -+ // LLP_CNT : r/o -+ channel_cmds[1] = 0; -+ -+ if (0 == -+ (ch_req->flags & (DMAD_FLAGS_RING_MODE | DMAD_FLAGS_BIDIRECTION))) -+ ahb_req->tx_dir = 0; -+ -+ dmad_ahb_config_dir(ch_req, channel_cmds); -+ -+ outl(channel_cmds[0], channel_base + DMAC_CSR_OFFSET); -+ outl(channel_cmds[1], channel_base + DMAC_CFG_OFFSET); -+ -+ /* SRCADR and DESADR */ -+ outl(0, (addr_t) drq->src_port); -+ outl(0, (addr_t) drq->dst_port); -+ -+ /* CYC (transfer size) */ -+ outl(0, (addr_t) drq->cyc_port); -+ -+ /* LLP */ -+ outl(0, channel_base + DMAC_LLP_OFFSET); -+ -+ /* TOT_SIZE - not now */ -+ -+_safe_exit: -+ -+ spin_unlock_irqrestore(&dmad.drq_pool_lock, lock_flags); -+ -+ return err; -+} -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+/** -+ * dmad_apb_isr - APB DMA interrupt service routine -+ * -+ * @irq : [in] The irq number -+ * @dev_id : [in] The identifier to identify the asserted channel -+ * -+ * This is the ISR that services all APB DMA channels. -+ */ -+static irqreturn_t dmad_apb_isr(int irq, void *dev_id) -+{ -+ dmad_drq *drq; -+ dmad_drb *drb, *drb_iter; -+ u32 channel = ((u32) dev_id) - 1; -+ u32 status; -+ u8 finish_int = 0; -+ u8 err_int = 0; -+ u8 cpl_events = 1; -+ -+ dmad_dbg("%s() >> channel(%d)\n", __func__, channel); -+ -+ if (channel >= DMAD_APB_MAX_CHANNELS) { -+ dmad_err("%s() invlaid channel number: %d!\n", -+ __func__, channel); -+ return IRQ_HANDLED; -+ } -+ -+ /* Lookup channel's DRQ (DMA Request Queue) */ -+ drq = (dmad_drq *) & dmad.apb_drq_pool[channel]; -+ -+ /* - Check DMA status register to get channel number */ -+ status = inl((addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ -+ if (likely(status & APBBR_DMA_FINTST_MASK)) { -+ -+ /*dmad_dbg("apb dma int status: finish (0x%08x)\n", status); */ -+ finish_int = 1; -+ -+ /* APB DMA finish int status clear */ -+ clrbl(APBBR_DMA_FINTST_BIT, -+ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ -+ } else if (status & APBBR_DMA_ERRINTST_MASK) { -+ -+ /* Perform DMA error checking if no valid channel was found -+ * who assert the finish signal. */ -+ dmad_err("apb dma int status: err (0x%08x)\n", status); -+ -+ /* Mark as error int */ -+ err_int = 1; -+ -+ /* APB DMA error int status clear */ -+ clrbl(APBBR_DMA_ERRINTST_BIT, -+ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ -+ } else { -+ -+ dmad_err("%s() possible false-fired apb dma int," -+ " channel %d status-reg: 0x%08x\n", -+ __func__, channel, status); -+ -+ /* Stop DMA channel (make sure the channel will be stopped) */ -+ clrbl(APBBR_DMA_CHEN_BIT, -+ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ -+ return IRQ_HANDLED; -+ } -+ -+ /* Stop DMA channel (make sure the channel will be stopped) */ -+ dmad_disable_channel(drq); -+ -+ spin_lock(&drq->drb_pool_lock); -+ -+ /* Lookup/detach latest submitted DRB (DMA Request Block) from */ -+ /* the DRQ (DMA Request Queue), so ISR could kick off next DRB */ -+ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); -+ -+ if (unlikely(drb == NULL)) { -+ spin_unlock(&drq->drb_pool_lock); -+ return IRQ_HANDLED; -+ } -+ -+ /* release blocking of drb-allocation, if any ... */ -+ if (unlikely((drq->fre_head == 0) && -+ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK))) { -+ complete_all(&drq->drb_alloc_sync); -+ } -+ -+ /* Process DRBs according to the cause of this interrupt */ -+ if (likely(finish_int)) { -+ -+ if (drb->req_cycle == 0) -+ cpl_events = 0; -+ -+ /* Mark DRB state as completed */ -+ drb->state = DMAD_DRB_STATE_COMPLETED; -+ if (cpl_events && drb->sync) -+ complete_all(drb->sync); -+ -+ dmad_attach_tail(drq->drb_pool, &drq->fre_head, -+ &drq->fre_tail, drb->node); -+ -+ /* Check whether there are pending requests in the DRQ */ -+ if (drq->sbt_head != 0) { -+ -+ /* Lookup next DRB (DMA Request Block) */ -+ drb_iter = &drq->drb_pool[drq->sbt_head]; -+ -+ dmad_dbg("exec drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x)\n", -+ drb_iter->node, (u32) drb_iter, -+ drb_iter->src_addr, drb_iter->dst_addr, -+ drb_iter->req_cycle); -+ -+ /* Kick-off DMA for next DRB */ -+ /* - Source and destination address */ -+ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { -+ outl(drb_iter->addr1, drq->src_port); -+ outl(drb_iter->addr0, drq->dst_port); -+ } else { -+ outl(drb_iter->addr0, drq->src_port); -+ outl(drb_iter->addr1, drq->dst_port); -+ } -+ -+ /* - Transfer size (in units of source width) */ -+ outl(drb_iter->req_cycle, drq->cyc_port); -+ -+ /* Kick off next request */ -+ dmad_enable_channel(drq); -+ -+ drb_iter->state = DMAD_DRB_STATE_EXECUTED; -+ -+ } else { -+ /* No pending requests, keep the DMA channel stopped */ -+ } -+ -+ } else if (err_int) { -+ -+ dmad_err("%s() apb dma channel %d error!\n", __func__, channel); -+ -+ /* Zero out src, dst, and size */ -+ outl(0, drq->src_port); -+ outl(0, drq->dst_port); -+ outl(0, drq->cyc_port); -+ -+ /* Remove all pending requests in the queue */ -+ drb_iter = drb; -+ while (drb_iter) { -+ -+ dmad_err("abort drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x)\n", -+ drb_iter->node, (u32) drb_iter, -+ drb_iter->src_addr, drb_iter->dst_addr, -+ drb_iter->req_cycle); -+ -+ if (drb_iter->req_cycle == 0) -+ cpl_events = 0; -+ -+ /* Mark DRB state as abort */ -+ drb_iter->state = DMAD_DRB_STATE_ABORT; -+ -+ if (cpl_events && drb_iter->sync) -+ complete_all(drb_iter->sync); -+ -+ dmad_attach_tail(drq->drb_pool, &drq->fre_head, -+ &drq->fre_tail, drb_iter->node); -+ -+ dmad_detach_head(drq->drb_pool, &drq->sbt_head, -+ &drq->sbt_tail, &drb_iter); -+ } -+ } -+ -+ spin_unlock(&drq->drb_pool_lock); -+ -+ /* dispatch interrupt-context level callbacks */ -+ if (cpl_events && drq->completion_cb) { -+ /* signal DMA driver that new node is available */ -+ drq->completion_cb(channel, status, drq->completion_data); -+ } -+ -+ dmad_dbg("%s() <<\n", __func__); -+ -+ return IRQ_HANDLED; -+} -+ -+/** -+ * dmad_apb_config_dir - prepare command reg according to tx direction -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @channel_cmds : [out] Reference to array of command words to be prepared with -+ * @return : none -+ * -+ * Prepare command registers according to transfer direction ... -+ * channel_cmd[0] APBBR_DMA_CMD -+ * -+ * This function only serves as local helper. No protection wrappers. -+ */ -+static void dmad_apb_config_dir(dmad_chreq * ch_req, addr_t * channel_cmds) -+{ -+ dmad_drq *drq = (dmad_drq *) ch_req->drq; -+ dmad_apb_chreq *apb_req = (dmad_apb_chreq *) (&ch_req->apb_req); -+ -+ dmad_dbg("%s() channel_cmd(0x%08x)\n", __func__, channel_cmds[0]); -+ -+ *channel_cmds &= ~(addr_t) -+ (APBBR_DMA_SRCADDRINC_MASK | APBBR_DMA_DSTADDRINC_MASK | -+ APBBR_DMA_DSTADDRSEL_MASK | APBBR_DMA_DREQSEL_MASK | -+ APBBR_DMA_SRCADDRSEL_MASK | APBBR_DMA_SREQSEL_MASK); -+ -+ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ -+ if (apb_req->tx_dir == 0) { -+ -+ dmad_dbg("%s() addr0 --> addr1\n", __func__); -+ -+ /* APB Bridge DMA (Channel Setting) -+ * - CMD -+ * SRCADR : apb_req->src_ctrl -+ * DESADR : apb_req->dst_ctrl -+ */ -+ *channel_cmds |= -+ (((apb_req->addr0_ctrl << APBBR_DMA_SRCADDRINC_SHIFT) & -+ APBBR_DMA_SRCADDRINC_MASK) | -+ ((apb_req->addr1_ctrl << APBBR_DMA_DSTADDRINC_SHIFT) & -+ APBBR_DMA_DSTADDRINC_MASK)); -+ -+ /* - CMD -+ * DESADRSEL : AHB/APB, driver auto-conf -+ * DREQSEL -+ */ -+ *channel_cmds |= -+ ((addr_t) (APBBR_DMA_DSTADDRSEL_MASK & -+ (apb_reqn_route_table[apb_req->addr1_reqn]. -+ bus_sel << APBBR_DMA_DSTADDRSEL_BIT)) | -+ (((addr_t) apb_req-> -+ addr1_reqn << APBBR_DMA_DREQSEL_SHIFT) & -+ APBBR_DMA_DREQSEL_MASK)); -+ -+ /* - CMD -+ * SRCADRSEL : AHB/APB, driver auto-conf -+ * SREQSEL -+ */ -+ *channel_cmds |= -+ ((addr_t) (APBBR_DMA_SRCADDRSEL_MASK & -+ (apb_reqn_route_table[apb_req->addr0_reqn]. -+ bus_sel << APBBR_DMA_SRCADDRSEL_BIT)) | -+ (((addr_t) apb_req-> -+ addr0_reqn << APBBR_DMA_SREQSEL_SHIFT) & -+ APBBR_DMA_SREQSEL_MASK)); -+ -+ drq->flags &= ~(addr_t) DMAD_DRQ_DIR_A1_TO_A0; -+ -+ } else { -+ -+ dmad_dbg("%s() addr0 <-- addr1\n", __func__); -+ -+ /* APB Bridge DMA (Channel Setting) -+ * - CMD -+ * SRCADR : apb_req->src_ctrl -+ * DESADR : apb_req->dst_ctrl -+ */ -+ *channel_cmds |= -+ (((apb_req->addr1_ctrl << APBBR_DMA_SRCADDRINC_SHIFT) & -+ APBBR_DMA_SRCADDRINC_MASK) | -+ ((apb_req->addr0_ctrl << APBBR_DMA_DSTADDRINC_SHIFT) & -+ APBBR_DMA_DSTADDRINC_MASK)); -+ -+ /* - CMD -+ * DESADRSEL : AHB/APB, driver auto-conf -+ * DREQSEL -+ */ -+ *channel_cmds |= ((addr_t) (APBBR_DMA_DSTADDRSEL_MASK & -+ (apb_reqn_route_table -+ [apb_req->addr0_reqn]. -+ bus_sel << -+ APBBR_DMA_DSTADDRSEL_BIT)) | -+ (((addr_t) apb_req-> -+ addr0_reqn << APBBR_DMA_DREQSEL_SHIFT) & -+ APBBR_DMA_DREQSEL_MASK)); -+ -+ /* - CMD -+ * SRCADRSEL : AHB/APB, driver auto-conf -+ * SREQSEL -+ */ -+ *channel_cmds |= ((addr_t) (APBBR_DMA_SRCADDRSEL_MASK & -+ (apb_reqn_route_table -+ [apb_req->addr1_reqn]. -+ bus_sel << -+ APBBR_DMA_SRCADDRSEL_BIT)) | -+ (((addr_t) apb_req-> -+ addr1_reqn << APBBR_DMA_SREQSEL_SHIFT) & -+ APBBR_DMA_SREQSEL_MASK)); -+ -+ drq->flags |= (addr_t) DMAD_DRQ_DIR_A1_TO_A0; -+ } -+ -+ dmad_dbg("%s() channel_cmd(0x%08x)\n", __func__, channel_cmds[0]); -+} -+ -+/** -+ * dmad_apb_init - initialize a apb dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * Register APB DMA ISR and performs hw initialization for the given DMA -+ * channel. -+ */ -+static int dmad_apb_init(dmad_chreq * ch_req) -+{ -+ int err = 0; -+ dmad_drq *drq = (dmad_drq *) ch_req->drq; -+ dmad_apb_chreq *apb_req = (dmad_apb_chreq *) (&ch_req->apb_req); -+ u32 channel = (u32) ch_req->channel; -+ addr_t channel_cmd = 0; -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ /* register interrupt handler */ -+ err = request_irq(apb_irqs[channel], dmad_apb_isr, 0, -+ "APB_DMA", (void *)(channel + 1)); -+ if (unlikely(err != 0)) { -+ dmad_err("unable to request IRQ %d for APB DMA (error %d)\n", -+ apb_irqs[channel], err); -+ free_irq(apb_irqs[channel], (void *)(channel + 1)); -+ return err; -+ } -+ -+ spin_lock_irqsave(&dmad.drq_pool_lock, lock_flags); -+ -+ /********************************************************** -+ * Following code require _safe_exit return path -+ */ -+ -+#ifdef CONFIG_PLAT_AG102 -+ -+ /* PCU -+ * -+ */ -+ //ADD by river 2010.10.20 -+ if (unlikely((apb_req->src_reqn > APBBR_REQN_MAX) || -+ (apb_req->dst_reqn > APBBR_REQN_MAX))) { -+ dmad_err("Invalid source reqn(%d) or destination reqn(%d)\n", -+ apb_req->src_reqn, apb_req->dst_reqn); -+ err = -EBADR; -+ goto _safe_exit; -+ } -+ -+ if (apb_req->src_reqn != APBBR_REQN_NONE) { -+ u32 ahb_reqn; -+ -+ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_tx; -+ else -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_rx; -+ -+ } -+ -+ if (apb_req->dst_reqn != APBBR_REQN_NONE) { -+ u32 ahb_reqn; -+ -+ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_tx; -+ else -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_rx; -+ -+ } -+ //End ADD by river 2010.10.20 -+ -+#else /* CONFIG_PLAT_AG102 */ -+ -+ /* PMU -+ * - Undo APB device DMA to AHB DMAC channel routing. (connection status -+ * is obtained from reading back the PMU_AHBDMA_REQACK register) -+ */ -+ if (unlikely((apb_req->src_reqn > APBBR_REQN_MAX) || -+ (apb_req->dst_reqn > APBBR_REQN_MAX))) { -+ dmad_err("Invalid source reqn(%d) or destination reqn(%d)\n", -+ apb_req->src_reqn, apb_req->dst_reqn); -+ err = -EBADR; -+ goto _safe_exit; -+ } -+ -+ if (apb_req->src_reqn != APBBR_REQN_NONE) { -+ u32 ahb_reqn; -+ -+ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_tx; -+ else -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->src_reqn].ahb_reqn_rx; -+ -+ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); -+ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); -+ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); -+ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); -+ } -+ -+ if (apb_req->dst_reqn != APBBR_REQN_NONE) { -+ u32 ahb_reqn; -+ -+ if (apb_req->tx_dir == DMAD_DIR_A0_TO_A1) -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_tx; -+ else -+ ahb_reqn = -+ apb_reqn_route_table[apb_req->dst_reqn].ahb_reqn_rx; -+ -+ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); -+ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); -+ outl(0, ahb_ch_route_table[ahb_reqn].clear_cr); -+ outl(0, ahb_ch_route_table[ahb_reqn].route_cr); -+ } -+#endif /* CONFIG_PLAT_AG102 */ -+ -+ /* APB Bridge DMA (Channel Setting) -+ * - CMD -+ * ENBDIS : 0 (disable for now) -+ * FININTSTS : 0 (clear finishing interrupt status) -+ * FININTENB : 1 (enable finishing interrupt) -+ * BURMOD : apb_req->burst_mode -+ * ERRINTSTS : 0 (clear error interrupt status) -+ * ERRINTENB : 1 (enable error interrupt) -+ * SRCADRSEL : AHB/APB, driver auto-conf -+ * DESADRSEL : AHB/APB, driver auto-conf -+ * SRCADR : apb_req->src_ctrl -+ * DESADR : apb_req->dst_ctrl -+ * REQSEL : apb_req->src_reqn -+ * DATAWIDTH : apb_req->data_width -+ */ -+ -+ /* - CMD -+ * ENBDIS -+ * FININTSTS -+ * FININTENB -+ * BURMOD -+ * ERRINTSTS -+ * ERRINTENB -+ * DATAWIDTH -+ */ -+ channel_cmd = -+ ((addr_t) APBBR_DMA_FINTEN_MASK | APBBR_DMA_ERRINTEN_MASK | -+ ((apb_req-> -+ burst_mode << APBBR_DMA_BURST_BIT) & APBBR_DMA_BURST_MASK) | -+ ((apb_req-> -+ data_width << APBBR_DMA_DATAWIDTH_SHIFT) & -+ APBBR_DMA_DATAWIDTH_MASK)); -+ -+ /* - CMD -+ * SRCADRSEL -+ * DESADRSEL -+ * SRCADR -+ * DESADR -+ * REQSEL -+ */ -+ if (0 == -+ (ch_req->flags & (DMAD_FLAGS_RING_MODE | DMAD_FLAGS_BIDIRECTION))) -+ apb_req->tx_dir = 0; -+ dmad_apb_config_dir(ch_req, &channel_cmd); -+ -+ /* - CMD outport */ -+ outl(channel_cmd, (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ -+ /* SRCADR and DESADR */ -+ outl(0, (addr_t) drq->src_port); -+ outl(0, (addr_t) drq->dst_port); -+ -+ /* CYC (transfer size) */ -+ outl(0, (addr_t) drq->cyc_port); -+ -+ /* keep channel data width for faster cycle/byte size conversion */ -+ drq->data_width = apb_req->data_width; -+ -+_safe_exit: -+ -+ spin_unlock_irqrestore(&dmad.drq_pool_lock, lock_flags); -+ -+ return err; -+} -+ -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+/** -+ * dmad_channel_init - initialize given dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * This function serves as the abstraction layer of dmad_ahb_init() -+ * and dmad_apb_init() functions. -+ */ -+static int dmad_channel_init(dmad_chreq * ch_req) -+{ -+ int err = 0; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) -+ return -EFAULT; -+ -+ if (unlikely(ch_req->drq == NULL)) -+ return -EBADR; -+ -+ /* Initialize DMA controller */ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) -+ err = dmad_ahb_init(ch_req); -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) -+ err = dmad_apb_init(ch_req); -+#endif -+ -+ return err; -+} -+ -+static inline void dmad_reset_channel(dmad_drq * drq) -+{ -+ /* disable dma controller */ -+ dmad_disable_channel(drq); -+ -+ /* Source and destination address */ -+ outl(0, drq->src_port); -+ outl(0, drq->dst_port); -+ -+ /* Transfer size (in units of source width) */ -+ outl(0, drq->cyc_port); -+} -+ -+/** -+ * dmad_channel_reset - reset given dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * This function serves as the abstraction layer of dmad_ahb_reset() -+ * and dmad_apb_reset() functions. -+ */ -+static int dmad_channel_reset(dmad_chreq * ch_req) -+{ -+ u32 channel = (u32) ch_req->channel; -+ unsigned long lock_flags; -+ int err = 0; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) -+ return -EFAULT; -+ -+ if (unlikely(ch_req->drq == NULL)) -+ return -EBADR; -+ -+ spin_lock_irqsave(&((dmad_drq *) ch_req->drq)->drb_pool_lock, -+ lock_flags); -+ -+ /* stop DMA channel */ -+ dmad_reset_channel((dmad_drq *) ch_req->drq); -+ -+ spin_unlock_irqrestore(&((dmad_drq *) ch_req->drq)->drb_pool_lock, -+ lock_flags); -+ -+ /* unregister interrupt handler */ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) -+ free_irq(ahb_irqs[channel], (void *)(channel + 1)); -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) -+ free_irq(apb_irqs[channel], (void *)(channel + 1)); -+#endif -+ -+ return err; -+} -+ -+/** -+ * dmad_channel_alloc - allocates and initialize a dma channel -+ * @ch_req : [in/out] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * This function allocates a DMA channel according to client's request -+ * parameters. ISR and HW state will also be initialized accordingly. -+ */ -+int dmad_channel_alloc(dmad_chreq * ch_req) -+{ -+ dmad_drq *drq_iter = NULL; -+ dmad_drb *drb_iter; -+ int err = 0; -+ u32 i = 0; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (ch_req == NULL) { -+ printk(KERN_ERR "%s() invalid argument!\n", __func__); -+ return -EFAULT; -+ } -+ -+ spin_lock(&dmad.drq_pool_lock); -+ -+ /* locate an available DMA channel */ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ -+ drq_iter = dmad.ahb_drq_pool; -+ -+ if ((ch_req->ahb_req.src_reqn != DMAC_REQN_NONE) || -+ (ch_req->ahb_req.dst_reqn != DMAC_REQN_NONE)) { -+ /* [2007-12-03] It looks current board have problem to -+ * do dma traffic for APB devices on DMAC channel 0/1. -+ * Redirect all APB devices to start from channel 2. -+ */ -+ -+ /* [todo] include USB controller ? */ -+ drq_iter = &dmad.ahb_drq_pool[2]; -+ for (i = 2; i < DMAD_AHB_MAX_CHANNELS; ++i, ++drq_iter) { -+ if (!(drq_iter->state & DMAD_DRQ_STATE_READY)) -+ break; -+ } -+ } else { -+ /* channel for other devices is free to allocate */ -+ for (i = 0; i < DMAD_AHB_MAX_CHANNELS; ++i, ++drq_iter) { -+ if (!(drq_iter->state & DMAD_DRQ_STATE_READY)) -+ break; -+ } -+ } -+ -+ if (unlikely(i == DMAD_AHB_MAX_CHANNELS)) { -+ spin_unlock(&dmad.drq_pool_lock); -+ dmad_err("out of available channels (AHB DMAC)!\n"); -+ return -ENOSPC; -+ } -+ -+ dmad_dbg("allocated channel: %d (AHB DMAC)\n", i); -+ -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ -+ drq_iter = dmad.apb_drq_pool; -+ -+ for (i = 0; i < DMAD_APB_MAX_CHANNELS; ++i, ++drq_iter) { -+ if ((drq_iter->state & DMAD_DRQ_STATE_READY) == 0) -+ break; -+ } -+ -+ if (unlikely(i == DMAD_APB_MAX_CHANNELS)) { -+ spin_unlock(&dmad.drq_pool_lock); -+ dmad_err("out of available channels (APB DMAC)!\n"); -+ return -ENOSPC; -+ } -+ -+ dmad_dbg("allocated channel: %d (APB DMAC)\n", i); -+ } -+#endif -+ if (drq_iter == NULL) { -+ spin_unlock(&dmad.drq_pool_lock); -+ printk(KERN_ERR "%s() invalid argument!\n", __func__); -+ return -EFAULT; -+ } -+ -+ spin_unlock(&dmad.drq_pool_lock); -+ memset(drq_iter, 0, sizeof(dmad_drq)); -+ -+ /* Initialize DMA channel's DRB pool as list of free DRBs */ -+ drq_iter->drb_pool = -+ kmalloc(DMAD_DRB_POOL_SIZE * sizeof(dmad_drb), GFP_ATOMIC); -+ -+ if (drq_iter->drb_pool == NULL) { -+ printk(KERN_ERR "%s() failed to allocate drb pool!\n", -+ __func__); -+ return -ENOMEM; -+ } -+ -+ /* Allocate the DMA channel */ -+ drq_iter->state = DMAD_DRQ_STATE_READY; -+ drq_iter->flags = ch_req->flags; -+ -+ /* Initialize synchronization object for DMA queue access control */ -+ spin_lock_init(&drq_iter->drb_pool_lock); -+ -+ /* Initialize synchronization object for free drb notification */ -+ init_completion(&drq_iter->drb_alloc_sync); -+ -+ /* Record the channel number in client's struct */ -+ ch_req->channel = i; -+ -+ /* Record the channel's queue handle in client's struct */ -+ ch_req->drq = drq_iter; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ drq_iter->channel_base = (addr_t) DMAC_BASE_CH(i); -+ drq_iter->enable_port = -+ (addr_t) drq_iter->channel_base + DMAC_CSR_OFFSET; -+ drq_iter->src_port = -+ (addr_t) drq_iter->channel_base + DMAC_SRC_ADDR_OFFSET; -+ drq_iter->dst_port = -+ (addr_t) drq_iter->channel_base + DMAC_DST_ADDR_OFFSET; -+ drq_iter->cyc_port = -+ (addr_t) drq_iter->channel_base + DMAC_SIZE_OFFSET; -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ drq_iter->channel_base = (addr_t) APBBR_DMA_BASE_CH(i); -+ drq_iter->enable_port = -+ (addr_t) drq_iter->channel_base + APBBR_DMA_CMD_OFFSET; -+ drq_iter->src_port = -+ (addr_t) drq_iter->channel_base + APBBR_DMA_SAD_OFFSET; -+ drq_iter->dst_port = -+ (addr_t) drq_iter->channel_base + APBBR_DMA_DAD_OFFSET; -+ drq_iter->cyc_port = -+ (addr_t) drq_iter->channel_base + APBBR_DMA_CYC_OFFSET; -+ } -+#endif -+ /* drb-0 is an invalid node - for node validation */ -+ drb_iter = &drq_iter->drb_pool[0]; -+ drb_iter->prev = 0; -+ drb_iter->next = 0; -+ drb_iter->node = 0; -+ ++drb_iter; -+ -+ /* init other drbs - link in order */ -+ for (i = 1; i < DMAD_DRB_POOL_SIZE; ++i, ++drb_iter) { -+ drb_iter->prev = i - 1; -+ drb_iter->next = i + 1; -+ drb_iter->node = i; -+ } -+ drq_iter->drb_pool[DMAD_DRB_POOL_SIZE - 1].next = 0; -+ -+ /* Initialize channel's DRB free-list, ready-list, and submitted-list */ -+ drq_iter->fre_head = 1; -+ drq_iter->fre_tail = DMAD_DRB_POOL_SIZE - 1; -+ drq_iter->rdy_head = drq_iter->rdy_tail = 0; -+ drq_iter->sbt_head = drq_iter->sbt_tail = 0; -+ -+ /* initialize ring buffer mode resources */ -+ if (ch_req->flags & DMAD_FLAGS_RING_MODE) { -+ -+ int remnant = (int)ch_req->ring_size - -+ (int)ch_req->periods * (int)ch_req->period_size; -+ if (remnant == 0) { -+ drq_iter->periods = ch_req->periods; -+ } else if (remnant > 0) { -+ drq_iter->periods = ch_req->periods; // + 1; -+ } else { -+ dmad_err("%s() Error - buffer_size < " -+ "periods * period_size!\n", __func__); -+ err = -EFAULT; -+ goto _err_exit; -+ } -+ -+ drq_iter->ring_size = ch_req->ring_size; -+ drq_iter->period_size = ch_req->period_size; -+ drq_iter->remnant_size = (dma_addr_t) remnant; -+ -+ drq_iter->ring_base = (dma_addr_t) ch_req->ring_base; -+ drq_iter->dev_addr = (dma_addr_t) ch_req->dev_addr; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ if ((ch_req->ahb_req.ring_ctrl == DMAC_CSR_AD_DEC) || -+ (ch_req->ahb_req.dev_ctrl == DMAC_CSR_AD_DEC)) { -+ dmad_err("%s() Error - decremental" -+ " addressing DMA is not supported in" -+ " ring mode currently!\n", __func__); -+ err = -EFAULT; -+ goto _err_exit; -+ } -+ -+ if (ch_req->ahb_req.ring_ctrl == DMAC_CSR_AD_FIX) { -+ dmad_err("%s() Error - ring address control is " -+ "fixed in ring DMA mode!\n", __func__); -+ err = -EFAULT; -+ goto _err_exit; -+ } -+ -+ drq_iter->period_bytes = -+ DMAC_CYCLE_TO_BYTES(ch_req->period_size, -+ ch_req->ahb_req.ring_width); -+ -+ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ -+ if (ch_req->ahb_req.tx_dir == 0) -+ drq_iter->ring_port = -+ (addr_t) drq_iter->src_port; -+ else -+ drq_iter->ring_port = -+ (addr_t) drq_iter->dst_port; -+ -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ -+ if ((ch_req->apb_req.ring_ctrl >= APBBR_ADDRINC_D1) || -+ (ch_req->apb_req.dev_ctrl >= APBBR_ADDRINC_D1)) { -+ dmad_err("%s() Error - decremental" -+ " addressing DMA is not supported in" -+ " ring mode currently!\n", __func__); -+ err = -EFAULT; -+ goto _err_exit; -+ } -+ -+ if (ch_req->apb_req.ring_ctrl == APBBR_ADDRINC_FIXED) { -+ dmad_err("%s() Error - ring address control is " -+ "fixed in ring DMA mode!\n", __func__); -+ err = -EFAULT; -+ goto _err_exit; -+ } -+ -+ drq_iter->period_bytes = -+ APBBR_DMA_CYCLE_TO_BYTES(ch_req->period_size, -+ ch_req->apb_req. -+ data_width); -+ -+ /* 0 - addr0 to addr1; 1 - addr1 to addr0 */ -+ if (ch_req->apb_req.tx_dir == 0) -+ drq_iter->ring_port = -+ (addr_t) drq_iter->src_port; -+ else -+ drq_iter->ring_port = -+ (addr_t) drq_iter->dst_port; -+ } -+#endif -+ dmad_dbg("%s() ring: base(0x%08x) port(0x%08x) periods(0x%08x)" -+ " period_size(0x%08x) period_bytes(0x%08x)" -+ " remnant_size(0x%08x)\n", -+ __func__, drq_iter->ring_base, drq_iter->ring_port, -+ drq_iter->periods, drq_iter->period_size, -+ drq_iter->period_bytes, drq_iter->remnant_size); -+ } -+ -+ drq_iter->completion_cb = ch_req->completion_cb; -+ drq_iter->completion_data = ch_req->completion_data; -+ -+ /* Initialize the channel && register isr */ -+ err = dmad_channel_init(ch_req); -+ -+_err_exit: -+ -+ if (err != 0) { -+ spin_lock(&dmad.drq_pool_lock); -+ -+ kfree(drq_iter->drb_pool); -+ memset(drq_iter, 0, sizeof(dmad_drq)); -+ -+ ch_req->channel = -1; -+ ch_req->drq = (void *)0; -+ -+ spin_unlock(&dmad.drq_pool_lock); -+ -+ dmad_err("Failed to initialize APB DMA! " -+ "Channel allocation aborted!\n"); -+ } -+ -+ return err; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_channel_alloc); -+ -+/** -+ * dmad_channel_free - release a dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * This function releases a DMA channel. The channel is available for future -+ * allocation after the invokation. -+ */ -+int dmad_channel_free(dmad_chreq * ch_req) -+{ -+ dmad_drq *drq; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ if (unlikely((ch_req->channel < 0) || -+ ((drq->state & DMAD_DRQ_STATE_READY) == 0))) { -+ dmad_err("try to free a free channel!\n"); -+ return -EBADR; -+ } -+ -+ /* Stop/abort channel I/O -+ * (forced to shutdown and should be protected against isr) -+ */ -+ dmad_drain_requests(ch_req, 1); -+ dmad_channel_reset(ch_req); -+ -+ dmad_dbg("freed channel: %d\n", ch_req->channel); -+ -+ spin_lock(&dmad.drq_pool_lock); -+ -+ kfree(drq->drb_pool); -+ memset(drq, 0, sizeof(dmad_drq)); -+ -+ ch_req->drq = 0; -+ ch_req->channel = (u32) - 1; -+ -+ spin_unlock(&dmad.drq_pool_lock); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_channel_free); -+ -+/** -+ * dmad_channel_enable - enable/disable a dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @enable : [in] 1 to enable the channel, 0 to disable -+ * @return : 0 if success, non-zero if any error -+ * -+ * Enable or disable the given DMA channel. -+ */ -+int dmad_channel_enable(const dmad_chreq * ch_req, u8 enable) -+{ -+ dmad_drq *drq; -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) -+ return -EFAULT; -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) -+ return -EBADR; -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /* Enable/disable DMA channel */ -+ if (enable) -+ dmad_enable_channel(drq); -+ else -+ dmad_disable_channel(drq); -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_channel_enable); -+ -+/** -+ * dmad_config_channel_dir - config dma channel transfer direction -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @dir : [in] DMAD_DRQ_DIR_A0_TO_A1 or DMAD_DRQ_DIR_A1_TO_A0 -+ * @return : 0 if success, non-zero if any error -+ * -+ * Reconfigure the channel transfer direction. This function works only if -+ * the channel was allocated with the DMAD_FLAGS_BIDIRECTION flags. Note -+ * that bi-direction mode and ring mode are mutual-exclusive from user's -+ * perspective. -+ */ -+int dmad_config_channel_dir(dmad_chreq * ch_req, u8 dir) -+{ -+ dmad_drq *drq; -+ addr_t channel_cmds[2]; -+ unsigned long lock_flags; -+ u8 cur_dir; -+ -+ if (unlikely(ch_req == NULL)) -+ return -EFAULT; -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) -+ return -EBADR; -+ -+ if (unlikely(!(ch_req->flags & DMAD_FLAGS_BIDIRECTION))) { -+ dmad_err("%s() Channel is not configured as" -+ " bidirectional!\n", __func__); -+ return -EFAULT; -+ } -+ -+ cur_dir = drq->flags & DMAD_DRQ_DIR_MASK; -+ if (dir == cur_dir) { -+ dmad_dbg("%s() cur_dir(%d) == dir(%d) skip reprogramming hw.\n", -+ __func__, cur_dir, dir); -+ return 0; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ if (unlikely((drq->sbt_head != 0) /*||dmad_is_channel_enabled(drq) */ )) { -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ dmad_err("%s() Cannot change direction while the " -+ "channel has pending requests!\n", __func__); -+ return -EFAULT; -+ } -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ -+ channel_cmds[0] = -+ inl((addr_t) drq->channel_base + DMAC_CSR_OFFSET); -+ channel_cmds[1] = -+ inl((addr_t) drq->channel_base + DMAC_CFG_OFFSET); -+ -+ ch_req->ahb_req.tx_dir = dir; -+ dmad_ahb_config_dir(ch_req, channel_cmds); -+ -+ outl(channel_cmds[1], -+ (addr_t) drq->channel_base + DMAC_CFG_OFFSET); -+ outl(channel_cmds[0], -+ (addr_t) drq->channel_base + DMAC_CSR_OFFSET); -+ -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ -+ channel_cmds[0] = -+ inl((addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ -+ ch_req->apb_req.tx_dir = dir; -+ dmad_apb_config_dir(ch_req, channel_cmds); -+ -+ outl(channel_cmds[0], -+ (addr_t) drq->channel_base + APBBR_DMA_CMD_OFFSET); -+ } -+#endif -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_config_channel_dir); -+ -+/** -+ * dmad_max_size_per_drb - return maximum transfer size per drb -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : The maximum transfer size per drb, in bytes. -+ * -+ * Calculate the maximum transfer size per drb according to the setting of -+ * data width during channel initialization. -+ * -+ * Return size is aligned to 4-byte boundary; this ensures the alignment -+ * requirement of dma starting address if the function was used in a loop to -+ * separate a large size dma transfer. -+ */ -+u32 dmad_max_size_per_drb(dmad_chreq * ch_req) -+{ -+ addr_t size = 0; -+ addr_t data_width = (addr_t) ((dmad_drq *) ch_req->drq)->data_width; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ size = DMAC_CYCLE_TO_BYTES(DMAC_TOT_SIZE_MASK & ((addr_t) ~ 3), -+ data_width); -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ size = -+ APBBR_DMA_CYCLE_TO_BYTES(APBBR_DMA_CYC_MASK & -+ ((addr_t) ~ 3), data_width); -+ } -+#endif -+ dmad_dbg("%s() - 0x%08x bytes\n", __func__, size); -+ -+ return size; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_max_size_per_drb); -+ -+/** -+ * dmad_bytes_to_cycles - calculate drb transfer size, in cycles -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @byte_size : [in] The DMA transfer size to be converted, in bytes -+ * @return : The drb transfer size, in cycles. -+ * -+ * Calculate the drb transfer cycle according to the setting of channel data -+ * width and burst setting. -+ * -+ * AHB DMA : unit is number of "data width". -+ * APB DMA : unit is number of "data width * burst size" -+ * -+ * APB Note: According to specification, decrement addressing seems to regard -+ * the burst size setting. For code efficiency, -+ * dmad_make_req_cycles() does not take care of this case and might -+ * produce wrong result. -+ */ -+u32 dmad_bytes_to_cycles(dmad_chreq * ch_req, u32 byte_size) -+{ -+ addr_t cycle = 0; -+ addr_t data_width = (addr_t) ((dmad_drq *) ch_req->drq)->data_width; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ cycle = DMAC_BYTES_TO_CYCLE(byte_size, data_width); -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ cycle = APBBR_DMA_BYTES_TO_CYCLE(byte_size, data_width); -+ if (ch_req->apb_req.burst_mode) -+ cycle = cycle >> 2; -+ } -+#endif -+ -+ dmad_dbg("%s() - 0x%08x bytes --> 0x%08x cycles\n", -+ __func__, byte_size, cycle); -+ -+ return cycle; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_bytes_to_cycles); -+ -+/** -+ * dmad_alloc_drb_internal - allocate a dma-request-block of a dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @drb : [out] Reference to a drb pointer to receive the allocated drb -+ * @return : 0 if success, non-zero if any error -+ * -+ * Allocates a DRB (DMA request block) of the given DMA channel. DRB is a -+ * single dma request which will be pushed into the submission queue of the -+ * given DMA channel. This is a lightweight internal version of -+ * dmad_alloc_drb() majorly for use in ring mode. Critical access to the -+ * drb pool should be protected before entering this function. -+ */ -+static inline int dmad_alloc_drb_internal(dmad_drq * drq, dmad_drb ** drb) -+{ -+ /* Initialize drb ptr in case of fail allocation */ -+ *drb = NULL; -+ -+ if (unlikely(drq->fre_head == 0)) { -+ return -EAGAIN; -+ } -+ -+ dmad_detach_head(drq->drb_pool, &drq->fre_head, &drq->fre_tail, drb); -+ -+ dmad_attach_tail(drq->drb_pool, -+ &drq->rdy_head, &drq->rdy_tail, (*drb)->node); -+ -+ (*drb)->state = DMAD_DRB_STATE_READY; -+ (*drb)->sync = 0; -+ -+ dmad_dbg("%s() drb(%d 0x%08x)\n", __func__, (*drb)->node, (u32) (*drb)); -+ -+ return 0; -+} -+ -+/** -+ * dmad_alloc_drb - allocate a dma-request-block of a dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @drb : [out] Reference to a drb pointer to receive the allocated drb -+ * @return : 0 if success, non-zero if any error -+ * -+ * Allocates a DRB (DMA request block) of the given DMA channel. DRB is a -+ * single dma request which will be pushed into the submission queue of the -+ * given DMA channel. -+ */ -+int dmad_alloc_drb(dmad_chreq * ch_req, dmad_drb ** drb) -+{ -+ dmad_drq *drq; -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (likely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /* Initialize drb ptr in case of fail allocation */ -+ *drb = NULL; -+ -+ if (unlikely(drq->fre_head == 0)) { -+ -+ drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT; -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+_wait_for_free_drbs: -+ -+ /* Wait for free urbs */ -+ if (drq->flags & DMAD_FLAGS_SLEEP_BLOCK) { -+ -+ int timeout = -+ wait_for_completion_interruptible_timeout(&drq-> -+ drb_alloc_sync, -+ msecs_to_jiffies -+ (6000)); -+ -+ /* reset sync object */ -+ INIT_COMPLETION(drq->drb_alloc_sync); -+ -+ if (timeout < 0) { -+ dmad_err("%s() wait for" -+ " completion error! (%d)\n", -+ __func__, timeout); -+ return timeout; -+ } -+ -+ } else if (drq->flags & DMAD_FLAGS_SPIN_BLOCK) { -+ -+ u32 timeout = 0x00ffffff; -+ -+ while ((drq->fre_head == 0) && (--timeout != 0)) { -+ } -+ if (timeout == 0) { -+ dmad_err("%s() polling wait for " -+ "completion timeout!\n", __func__); -+ return -EAGAIN; -+ } -+ -+ } else { -+ return -EAGAIN; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /* check whether all the requests of the channel has been -+ * abandoned or not */ -+ if (unlikely(drq->state & DMAD_DRQ_STATE_ABORT)) { -+ dmad_dbg("%s() drb-allocation aborted due" -+ " to cancel-request ...\n", __func__); -+ drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT; -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -ECANCELED; -+ } -+ -+ /* check again to avoid non-atomic operation between above -+ * two calls */ -+ if (unlikely(drq->fre_head == 0)) { -+ dmad_dbg("%s() lost free drbs ... " -+ "continue waiting ...\n", __func__); -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ goto _wait_for_free_drbs; -+ } -+ } -+ -+ dmad_detach_head(drq->drb_pool, &drq->fre_head, &drq->fre_tail, drb); -+ -+ dmad_attach_tail(drq->drb_pool, -+ &drq->rdy_head, &drq->rdy_tail, (*drb)->node); -+ -+ (*drb)->state = DMAD_DRB_STATE_READY; -+ (*drb)->sync = 0; -+ -+ dmad_dbg("%s() drb(%d 0x%08x)\n", __func__, (*drb)->node, (u32) (*drb)); -+ -+ drq->state &= (u32) ~ DMAD_DRQ_STATE_ABORT; -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_alloc_drb); -+ -+/** -+ * dmad_free_drb - free a dma-request-block of a dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @drb : [in] Reference to a drb to be freed -+ * @return : 0 if success, non-zero if any error -+ * -+ * Frees a DRB (DMA request block) of the given DMA channel. DRB is a -+ * single dma request which will be pushed into the submission queue of the -+ * given DMA channel. -+ */ -+int dmad_free_drb(dmad_chreq * ch_req, dmad_drb * drb) -+{ -+ dmad_drq *drq; -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /**************************************************** -+ * Following code requires _safe_exit return path -+ */ -+ -+ if (unlikely((drq->rdy_head == 0) || (drb->node == 0) || -+ (drb->state != DMAD_DRB_STATE_READY) || -+ (drb->node >= DMAD_DRB_POOL_SIZE))) { -+ dmad_err("Ready-queue is empty or invalid node!\n"); -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -EBADR; -+ } -+ -+ dmad_detach_node(drq->drb_pool, -+ &drq->rdy_head, &drq->rdy_tail, drb->node); -+ dmad_attach_tail(drq->drb_pool, -+ &drq->fre_head, &drq->fre_tail, drb->node); -+ -+ drb->state = DMAD_DRB_STATE_FREE; -+ drb->sync = 0; -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_free_drb); -+ -+/** -+ * dmad_submit_request_internal - submit a dma-request-block to the dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @drb : [in] Reference to a drb to be submitted -+ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due -+ * to finishing its previous request -+ * @return : 0 if success, non-zero if any error -+ * -+ * Submit a DRB (DMA request block) of the given DMA channel to submission -+ * queue. DRB is a single dma request which will be pushed into the -+ * submission queue of the given DMA channel. This is a lightweight internal -+ * version of dmad_alloc_drb() majorly for use in ring mode. Critical access to -+ * the drb pool should be protected before entering this function. -+ */ -+static inline int dmad_submit_request_internal(dmad_drq * drq, dmad_drb * drb) -+{ -+ if (drb->state == DMAD_DRB_STATE_READY) { -+ /* Detach user node from ready list */ -+ dmad_detach_node(drq->drb_pool, -+ &drq->rdy_head, &drq->rdy_tail, drb->node); -+ -+ dmad_attach_tail(drq->drb_pool, -+ &drq->sbt_head, &drq->sbt_tail, drb->node); -+ -+ drb->state = DMAD_DRB_STATE_SUBMITTED; -+ -+ dmad_dbg("%s() submit drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x) state(%d)\n", __func__, -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, drb->state); -+ } else { -+ dmad_dbg("%s() skip drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x)" -+ " size(0x%08x) state(%d)\n", __func__, -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, drb->state); -+ } -+ -+ return 0; -+} -+ -+/** -+ * dmad_submit_request - submit a dma-request-block to the dma channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @drb : [in] Reference to a drb to be submitted -+ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due -+ * to finishing its previous request -+ * @return : 0 if success, non-zero if any error -+ * -+ * Submit a DRB (DMA request block) of the given DMA channel to submission -+ * queue. DRB is a single dma request which will be pushed into the -+ * submission queue of the given DMA channel. -+ */ -+int dmad_submit_request(dmad_chreq * ch_req, dmad_drb * drb, u8 keep_fired) -+{ -+ dmad_drq *drq; -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /****************************************************** -+ * Following code require _safe_exit return path -+ */ -+ -+ if (unlikely((drq->rdy_head == 0) || (drb->node == 0) || -+ (drb->node >= DMAD_DRB_POOL_SIZE))) { -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -EBADR; -+ } -+ -+ /* Detach user node from ready list */ -+ dmad_detach_node(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, -+ drb->node); -+ -+ /* Queue DRB to the end of the submitted list */ -+ dmad_dbg("submit drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) sync(0x%08x) fire(%d)\n", -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, (u32) drb->sync, keep_fired); -+ -+ /* Check if submission is performed to an empty queue */ -+ if (unlikely(keep_fired && (drq->sbt_head == 0))) { -+ /* DMA is not running, so kick off transmission */ -+ dmad_dbg("kickoff dma engine.\n"); -+ -+ dmad_attach_tail(drq->drb_pool, -+ &drq->sbt_head, &drq->sbt_tail, drb->node); -+ -+ /* Source and destination address */ -+ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { -+ outl(drb->addr1, (addr_t) drq->src_port); -+ outl(drb->addr0, (addr_t) drq->dst_port); -+ } else { -+ outl(drb->addr0, (addr_t) drq->src_port); -+ outl(drb->addr1, (addr_t) drq->dst_port); -+ } -+ -+ /* Transfer size (in units of source width) */ -+ outl(drb->req_cycle, (addr_t) drq->cyc_port); -+ -+ /* Enable DMA channel (Kick off transmission when client -+ * enable it's transfer state) */ -+ dmad_enable_channel(drq); -+ -+ drb->state = DMAD_DRB_STATE_EXECUTED; -+ -+ } else { -+ /* DMA is already running, so only queue DRB to the end of the -+ * list */ -+ dmad_attach_tail(drq->drb_pool, -+ &drq->sbt_head, &drq->sbt_tail, drb->node); -+ drb->state = DMAD_DRB_STATE_SUBMITTED; -+ } -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_submit_request); -+ -+/** -+ * dmad_withdraw_request - cancel a submitted dma-request-block -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @drb : [in] Reference to a drb to be submitted -+ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due -+ * to finishing its previous request -+ * @return : 0 if success, non-zero if any error -+ * -+ * Cancel a submitted DRB (DMA request block) of the given DMA channel in its -+ * submission queue. DRB is a single dma request which will be pushed into the -+ * submission queue of the given DMA channel. Cancellation fails if the DRB has -+ * already been kicked off. -+ */ -+int dmad_withdraw_request(dmad_chreq * ch_req, dmad_drb * drb) -+{ -+ dmad_drq *drq = 0; -+ unsigned long lock_flags; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ -+ if (unlikely(drq->sbt_head == 0)) -+ return -EBADR; -+ -+ if (unlikely((drb->node == 0) || (drb->node >= DMAD_DRB_POOL_SIZE))) -+ return -EBADR; -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ if (unlikely((drq->sbt_head == 0) || (drb->node == 0) || -+ (drb->state != DMAD_DRB_STATE_SUBMITTED) || -+ (drb->node >= DMAD_DRB_POOL_SIZE))) { -+ dmad_err("Submitted-queue is empty or invalid node!\n"); -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -EBADR; -+ } -+ -+ dmad_dbg("cancel drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d)\n", -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, drb->state); -+ -+ if (unlikely(drb->state == DMAD_DRB_STATE_EXECUTED)) { -+ dmad_dbg("Already running drb cannot be stopped currently!\n"); -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return 0;/*-EBADR; */ -+ } -+ -+ dmad_detach_node(drq->drb_pool, -+ &drq->rdy_head, &drq->rdy_tail, drb->node); -+ dmad_attach_tail(drq->drb_pool, -+ &drq->fre_head, &drq->fre_tail, drb->node); -+ -+ drb->state = DMAD_DRB_STATE_FREE; -+ -+ if (drb->sync) -+ complete_all(drb->sync); -+ drb->sync = 0; -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_withdraw_request); -+ -+/** -+ * dmad_kickoff_requests_internal - kickoff hw DMA transmission -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * Kickoff hw DMA transmission of the given DMA channel. This function is -+ * valid for both ring & non-ring mode. This is a lightweight internal version -+ * of dmad_kickoff_requests() majorly for use in ring mode. Critical access to -+ * the drb pool should be protected before entering this function. -+ */ -+static inline int dmad_kickoff_requests_internal(dmad_drq * drq) -+{ -+ dmad_drb *drb; -+ -+ dmad_get_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); -+ -+ if (!drb) { -+ dmad_err("%s() null drb!\n", __func__); -+ return -EBADR; -+ } -+ -+ dmad_dbg("%s() drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d)\n", __func__, -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, drb->state); -+ -+ if (drb->state == DMAD_DRB_STATE_SUBMITTED) { -+ /* Transfer size (in units of source width) */ -+ outl(drb->req_cycle, (addr_t) drq->cyc_port); -+ -+ /* Source and destination address */ -+ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { -+ outl(drb->addr1, (addr_t) drq->src_port); -+ outl(drb->addr0, (addr_t) drq->dst_port); -+ } else { -+ outl(drb->addr0, (addr_t) drq->src_port); -+ outl(drb->addr1, (addr_t) drq->dst_port); -+ } -+ -+ drb->state = DMAD_DRB_STATE_EXECUTED; -+ } -+ -+ /* Enable DMA channel */ -+ if (!dmad_is_channel_enabled(drq)) { -+ dmad_enable_channel(drq); -+ } -+ -+ return 0; -+} -+ -+/** -+ * dmad_kickoff_requests - kickoff hw DMA transmission of the given DMA channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : 0 if success, non-zero if any error -+ * -+ * Kickoff hw DMA transmission of the given DMA channel. This function is -+ * valid for both ring & non-ring mode. -+ */ -+int dmad_kickoff_requests(dmad_chreq * ch_req) -+{ -+ dmad_drq *drq = 0; -+ dmad_drb *drb = 0; -+ unsigned long lock_flags; -+ dma_addr_t req_cycle; -+ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (unlikely(ch_req == NULL)) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ if (unlikely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ dmad_get_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); -+ -+ dmad_dbg("drq(0x%08x) channel_base(0x%08x)\n", -+ (u32) drq, drq->channel_base); -+ dmad_dbg("kick off drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d) a1_to_a0(%d)\n", -+ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, -+ drb->req_cycle, drb->state, -+ drq->flags & DMAD_DRQ_DIR_A1_TO_A0); -+ -+ /* do nothing if no drbs are in the submission queue */ -+ if (unlikely((drb == 0) || (drb->state != DMAD_DRB_STATE_SUBMITTED))) { -+ dmad_dbg("%s() invalid drb(%d 0x%08x) or drb-state(%d)!\n", -+ __func__, -+ drb->node, (u32) drb, drb ? drb->state : 0xffffffff); -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return 0; -+ } -+ -+ req_cycle = drb->req_cycle; -+ -+ if (unlikely(req_cycle == 0)) { -+ dmad_dbg("%s() zero transfer size!\n", __func__); -+ goto _safe_exit; -+ } -+ -+ /* Transfer size (in units of source width) */ -+ outl(req_cycle, (addr_t) drq->cyc_port); -+ -+ /* Source and destination address */ -+ if (drq->flags & DMAD_DRQ_DIR_A1_TO_A0) { -+ outl(drb->addr1, (addr_t) drq->src_port); -+ outl(drb->addr0, (addr_t) drq->dst_port); -+ } else { -+ outl(drb->addr0, (addr_t) drq->src_port); -+ outl(drb->addr1, (addr_t) drq->dst_port); -+ } -+ -+ drb->state = DMAD_DRB_STATE_EXECUTED; -+ -+ /* Enable DMA channel */ -+ dmad_enable_channel(drq); -+ -+_safe_exit: -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_kickoff_requests); -+ -+/** -+ * dmad_probe_hw_ptr_src - probe DMA source hw-address of the given channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : physical address of current HW source pointer -+ * -+ * Probe DMA source hw-address of the given channel. -+ */ -+dma_addr_t dmad_probe_hw_ptr_src(dmad_chreq * ch_req) -+{ -+ return (dma_addr_t) inl(((dmad_drq *) ch_req->drq)->src_port); -+} -+ -+EXPORT_SYMBOL_GPL(dmad_probe_hw_ptr_src); -+ -+/** -+ * dmad_probe_hw_ptr_dst - probe DMA destination hw-address of the given channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : physical address of current HW destination pointer -+ * -+ * Probe DMA destination hw-address of the given channel. -+ */ -+dma_addr_t dmad_probe_hw_ptr_dst(dmad_chreq * ch_req) -+{ -+ return (dma_addr_t) inl(((dmad_drq *) ch_req->drq)->dst_port); -+} -+ -+EXPORT_SYMBOL_GPL(dmad_probe_hw_ptr_dst); -+ -+/** -+ * dmad_update_ring - update DMA ring buffer base && size of the given channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @size : [in] The new ring buffer size, in unit of data width (cycles) -+ * @return : 0 if success, non-zero if any error -+ * -+ * Update DMA ring buffer size of the given channel. This function is valid -+ * only if the channel is initialized as ring buffer mode. -+ */ -+int dmad_update_ring(dmad_chreq * ch_req) -+{ -+ unsigned long lock_flags; -+ dmad_drq *drq = (dmad_drq *) ch_req->drq; -+ int remnant; -+ -+ if (unlikely(dmad_is_channel_enabled(drq))) { -+ dmad_err("%s() Error - dma channel should be " -+ "disabled before updating ring size!\n", __func__); -+ return -EFAULT; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /* todo: range checking */ -+ -+ remnant = (int)ch_req->ring_size - -+ (int)ch_req->periods * (int)ch_req->period_size; -+ if (remnant == 0) { -+ drq->periods = ch_req->periods; -+ } else if (remnant > 0) { -+ drq->periods = ch_req->periods; // + 1; -+ } else { -+ dmad_err("%s() Error - buffer_size < " -+ "periods * period_size!\n", __func__); -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -EFAULT; -+ } -+ -+ drq->ring_base = ch_req->ring_base; -+ drq->ring_size = ch_req->ring_size; -+ drq->period_size = ch_req->period_size; -+ drq->remnant_size = (dma_addr_t) remnant; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) { -+ drq->period_bytes = -+ DMAC_CYCLE_TO_BYTES(drq->period_size, drq->data_width); -+ } -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) { -+ drq->period_bytes = -+ APBBR_DMA_CYCLE_TO_BYTES(drq->period_size, drq->data_width); -+ } -+#endif -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ dmad_dbg("%s() ring: base(0x%08x) port(0x%08x) periods(0x%08x) " -+ "period_size(0x%08x) period_bytes(0x%08x) " -+ "remnant_size(0x%08x)\n", -+ __func__, drq->ring_base, drq->ring_port, -+ drq->periods, drq->period_size, drq->period_bytes, -+ drq->remnant_size); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_update_ring); -+ -+/** -+ * dmad_update_ring_sw_ptr - update DMA ring buffer sw-pointer -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @sw_ptr : [in] The new sw-pointer for the hw-pointer to chase of -+ * @keep_fired : [in] non-zero to kickoff dma even the channel has stopped due -+ * to finishing its previous request -+ * @return : 0 if success, non-zero if any error -+ * -+ * Update DMA ring buffer sw-pointer of the given channel on the fly. This -+ * function is valid only if the channel is initialized as ring buffer mode. -+ * Uint of sw_ptr is in number of dma data width. -+ */ -+int dmad_update_ring_sw_ptr(dmad_chreq * ch_req, -+ dma_addr_t sw_ptr, u8 keep_fired) -+{ -+ dmad_drq *drq; -+ unsigned long lock_flags; -+ dma_addr_t hw_off = 0, ring_ptr; -+ dma_addr_t sw_p_off, ring_p_off, period_size, period_bytes; -+ dma_addr_t remnant_size; -+ int sw_p_idx, ring_p_idx, period, periods; -+ dmad_drb *drb = NULL; -+ -+ /*if (ch_req == NULL) { */ -+ /* dmad_dbg("%s() null ch_req!\n", __func__); */ -+ /* return -EFAULT; */ -+ /*} */ -+ -+ drq = (dmad_drq *) ch_req->drq; -+ -+ /*if (drq == NULL) { */ -+ /* dmad_dbg("%s() null ch_req->drq!\n", __func__); */ -+ /* return -EBADR; */ -+ /*} */ -+ -+ if (unlikely(sw_ptr > drq->ring_size)) { -+ dmad_err("%s() Invalid ring buffer sw-pointer " -+ "range (0x%08x)! ring_size(0x%08x)\n", -+ __func__, sw_ptr, drq->ring_size); -+ return -EBADR; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ periods = drq->periods; -+ period_size = drq->period_size; -+ period_bytes = drq->period_bytes; -+ remnant_size = drq->remnant_size; -+ -+ ring_ptr = drq->sw_ptr; -+ ring_p_idx = drq->sw_p_idx; -+ ring_p_off = drq->sw_p_off; -+ -+ sw_p_idx = (int)(sw_ptr / period_size); -+ sw_p_off = sw_ptr % period_size; -+ -+ if (remnant_size && (sw_p_idx == periods)) { -+ --sw_p_idx; -+ sw_p_off += period_size; -+ } -+ -+ dmad_dbg("%s() ring_ptr(0x%08x) ring_p_idx(0x%08x) " -+ "ring_p_off(0x%08x)\n", -+ __func__, ring_ptr, ring_p_idx, ring_p_off); -+ dmad_dbg("%s() sw_ptr(0x%08x) sw_p_idx(0x%08x) sw_p_off(0x%08x)\n", -+ __func__, sw_ptr, sw_p_idx, sw_p_off); -+ -+ if (drq->ring_drb && -+ (drq->ring_drb->state & (DMAD_DRB_STATE_READY | -+ DMAD_DRB_STATE_SUBMITTED | -+ DMAD_DRB_STATE_EXECUTED))) { -+ drb = drq->ring_drb; -+ } else { -+ /* alloc new drb if there is none yet at ring_ptr */ -+ if (0 != dmad_alloc_drb_internal(drq, &drb)) { -+ dmad_err("%s() drb allocation failed!\n", __func__); -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -ENOSPC; -+ } -+ drb->addr0 = ((dma_addr_t) ring_p_idx * period_bytes) + -+ drq->ring_base; -+ drb->addr1 = drq->dev_addr; -+ drb->req_cycle = 0; // redundent, though, no harm to performance -+ -+ dmad_dbg("init_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d)\n", -+ (u32) drb->node, (u32) drb, drb->src_addr, -+ drb->dst_addr, drb->req_cycle, drb->state); -+ -+ drq->ring_drb = drb; -+ } -+ -+ /* Following code-path has been optimized. The design flow is expanded -+ * below for reference. -+ * -+ * if (sw_ptr >= ring_ptr) -+ * if (sw_p_idx == ring_p_idx) -+ * ring_drb::req_cycle <- sw_p_off -+ * if (ring_drb::state == executed) -+ * hw_cycle <- sw_p_idx -+ * fi -+ * else -+ * ring_drb::req_cycle <- period_size -+ * if (ring_drb::state == executed) -+ * hw_cycle <- period_size -+ * fi -+ * for (i = ring_p_idx+1 ~ sw_p_idx-1) -+ * new_drb::ring_addr <- i * period_bytes + ring_base -+ * new_drb::req_cycle <- period_size -+ * rof -+ * sw_drb::ring_addr <- sw_p_idx * period_bytes + ring_base -+ * sw_drb::req_cycle <- sw_p_off -+ * else -+ * // sw_ptr < ring_ptr -+ * ring_drb::req_cycle <- period_size -+ * if (ring_drb::state == executed) -+ * hw_cycle <- period_size -+ * fi -+ * for (i = ring_p_idx+1 ~ idx_max) -+ * new_drb::ring_addr <- i * period_bytes + ring_base -+ * new_drb::req_cycle <- period_size -+ * rof -+ * for (i = 0 ~ sw_p_idx-1) -+ * new_drb::ring_addr <- i * period_bytes + ring_base -+ * new_drb::req_cycle <- period_size -+ * rof -+ * sw_drb::ring_addr <- sw_p_idx * period_bytes + ring_base -+ * sw_drb::req_cycle <- sw_p_off -+ * fi -+ */ -+ if ((sw_ptr >= ring_ptr) && (sw_p_idx == ring_p_idx) && (sw_p_off != 0)) { -+ -+ dmad_dbg("update ring drb\n"); -+ -+ /* update drb size at ring_ptr */ -+ drb->req_cycle = sw_p_off; -+ -+ dmad_dbg("ring_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d)\n", -+ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, -+ drb->req_cycle, drb->state); -+ -+ /* update hw dma size of this drb if it has been sent to the -+ * controller */ -+ if (drb->state == DMAD_DRB_STATE_EXECUTED) { -+ dmad_disable_channel(drq); -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) -+ hw_off = DMAC_BYTES_TO_CYCLE((addr_t) -+ inl((addr_t) drq-> -+ ring_port) - -+ (addr_t) drb-> -+ addr0, -+ drq->data_width); -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) -+ hw_off = APBBR_DMA_BYTES_TO_CYCLE((addr_t) -+ inl((addr_t) -+ drq-> -+ ring_port) -+ - -+ (addr_t) drb-> -+ addr0, -+ drq-> -+ data_width); -+#endif -+ dmad_dbg("hw_off(0x%08x) sw_p_off(0x%08x)\n", -+ (u32) hw_off, (u32) sw_p_off); -+ -+ if (sw_p_off < hw_off) -+ dmad_err("%s() underrun! sw_p_off(0x%08x) <" -+ " hw_off(0x%08x)\n", __func__, -+ (u32) sw_p_off, (u32) hw_off); -+ else -+ outl(sw_p_off - hw_off, drq->cyc_port); -+ -+ dmad_enable_channel(drq); -+ -+ } else { -+ dmad_submit_request_internal(drq, drb); -+ } -+ -+ } else { -+ -+ dmad_dbg("fulfill ring drb - sw_ptr(0x%08x) ring_ptr(0x%08x)\n", -+ (u32) sw_ptr, (u32) ring_ptr); -+ -+ /* fulfill last drb at ring_ptr */ -+ if (ring_p_idx == (periods - 1)) -+ drb->req_cycle = period_size + remnant_size; -+ else -+ drb->req_cycle = period_size; -+ -+ dmad_dbg("ring_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d)\n", -+ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, -+ drb->req_cycle, drb->state); -+ -+ if (drb->state == DMAD_DRB_STATE_EXECUTED) { -+ dmad_disable_channel(drq); -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) -+ hw_off = DMAC_BYTES_TO_CYCLE((addr_t) -+ inl((addr_t) drq-> -+ ring_port) - -+ (addr_t) drb-> -+ addr0, -+ drq->data_width); -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) -+ hw_off = APBBR_DMA_BYTES_TO_CYCLE((addr_t) -+ inl((addr_t) -+ drq-> -+ ring_port) -+ - -+ (addr_t) drb-> -+ addr0, -+ drq-> -+ data_width); -+#endif -+ dmad_dbg("hw_off(0x%08x) period_size(0x%08x)\n", -+ (u32) hw_off, (u32) period_size); -+ -+ if (ring_p_idx == (periods - 1)) { -+ if (period_size < hw_off) -+ dmad_err("%s() illegal! " -+ "period_size(0x%08x) + " -+ "remnant_size(0x%08x) < " -+ "hw_off(0x%08x)\n", __func__, -+ (u32) period_size, -+ (u32) remnant_size, -+ (u32) hw_off); -+ else -+ outl(period_size + remnant_size - -+ hw_off, drq->cyc_port); -+ } else { -+ if (period_size < hw_off) -+ dmad_err("%s() illegal! " -+ "period_size(0x%08x) < " -+ "hw_off(0x%08x)\n", __func__, -+ (u32) period_size, -+ (u32) hw_off); -+ else -+ outl(period_size - hw_off, -+ drq->cyc_port); -+ } -+ -+ dmad_enable_channel(drq); -+ -+ } else { -+ dmad_submit_request_internal(drq, drb); -+ } -+ -+ ++ring_p_idx; -+ -+ /* adjust sw_ptr period index ahead by one ring cycle */ -+ //if (sw_ptr < ring_ptr) { -+ if (sw_p_idx < ring_p_idx) { -+ sw_p_idx += periods; -+ } -+ -+ /* allocate in-between (ring_ptr+1 to sw_ptr-1) -+ * full-cycle drbs */ -+ for (period = ring_p_idx; period < sw_p_idx; ++period) { -+ if (0 != dmad_alloc_drb_internal(drq, &drb)) { -+ dmad_err("%s() drb allocation failed!\n", -+ __func__); -+ spin_unlock_irqrestore(&drq->drb_pool_lock, -+ lock_flags); -+ return -ENOSPC; -+ } -+ -+ drb->addr0 = (dma_addr_t) (period % periods) * -+ period_bytes + drq->ring_base; -+ drb->addr1 = drq->dev_addr; -+ -+ if (period == (periods - 1)) { -+ drb->req_cycle = period_size + remnant_size; -+ } else { -+ drb->req_cycle = period_size; -+ } -+ -+ dmad_dbg("inbtw_drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x) state(%d)\n", -+ (u32) drb->node, (u32) drb, drb->addr0, -+ drb->addr1, drb->req_cycle, drb->state); -+ -+ dmad_submit_request_internal(drq, drb); -+ } -+ -+ /* allocate drb right at sw_ptr */ -+ if (0 != dmad_alloc_drb_internal(drq, &drb)) { -+ dmad_err("%s() drb allocation failed!\n", __func__); -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ return -ENOSPC; -+ } -+ drb->addr0 = (dma_addr_t) (sw_p_idx % periods) * -+ period_bytes + drq->ring_base; -+ drb->addr1 = drq->dev_addr; -+ drb->req_cycle = sw_p_off; -+ -+ dmad_dbg("swptr_drb(%d 0x%08x) addr0(0x%08x) addr1(0x%08x) " -+ "size(0x%08x) state(%d)\n", -+ (u32) drb->node, (u32) drb, drb->addr0, drb->addr1, -+ drb->req_cycle, drb->state); -+ -+ drq->ring_drb = drb; -+ -+ if (sw_p_off > 0) -+ dmad_submit_request_internal(drq, drb); -+ } -+ -+ drq->sw_ptr = sw_ptr % drq->ring_size; -+ drq->sw_p_idx = sw_p_idx % periods; -+ drq->sw_p_off = sw_p_off; -+ -+ if (likely(keep_fired)) { -+ dmad_kickoff_requests_internal(drq); -+ } -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ return 0; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_update_ring_sw_ptr); -+ -+/** -+ * dmad_probe_ring_hw_ptr - probe DMA ring buffer position of the given channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @return : Ring buffer position of current HW ring buffer pointer -+ * -+ * Probe DMA ring buffer position of the given channel. The position is -+ * relative to the ring buffer base. This function is valid only if the -+ * channel is initialized as ring buffer mode. -+ */ -+dma_addr_t dmad_probe_ring_hw_ptr(dmad_chreq * ch_req) -+{ -+ dmad_drq *drq = (dmad_drq *) ch_req->drq; -+ dma_addr_t cycles = -+ (dma_addr_t) inl(drq->ring_port) - (dma_addr_t) drq->ring_base; -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (ch_req->controller == DMAD_DMAC_AHB_CORE) -+ cycles = DMAC_BYTES_TO_CYCLE(cycles, drq->data_width); -+#endif -+#ifdef CONFIG_PLATFORM_APBDMA -+ if (ch_req->controller == DMAD_DMAC_APB_CORE) -+ cycles = APBBR_DMA_BYTES_TO_CYCLE(cycles, drq->data_width); -+#endif -+ return cycles; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_probe_ring_hw_ptr); -+ -+/** -+ * dmad_channel_drain - cancel DMA transmission of the given DMA channel -+ * @controller : [in] One of the enum value of DMAD_DMAC_CORE -+ * @drq : [in] Reference to the DMA queue structure (dmad_drq) -+ * @shutdown : [in] Non-zero to force a immediate channel shutdown -+ * @return : 0 if success, non-zero if any error -+ * -+ * Stop the DMA transmission and cancel all submitted requests of the given -+ * DMA channel. This function drains a single channel and is the internal -+ * implementation of the interface routine dmad_drain_requests() and the -+ * module_exit function. -+ */ -+static int dmad_channel_drain(u32 controller, dmad_drq * drq, u8 shutdown) -+{ -+ dmad_drb *drb = 0; -+ unsigned long lock_flags; -+ -+ if (unlikely(drq == NULL)) { -+ dmad_err("null ch_req->drq!\n"); -+ return -EBADR; -+ } -+ -+ spin_lock_irqsave(&drq->drb_pool_lock, lock_flags); -+ -+ /* Stop DMA channel if forced to shutdown immediately */ -+ if (shutdown) { -+ /* disable dma controller */ -+ dmad_reset_channel(drq); -+ -+ /* todo: more settings to stop DMA controller ?? */ -+ -+ /*if (drb->state == DMAD_DRB_STATE_EXECUTED) { */ -+ /*} */ -+ } -+ -+ /* Detach DRBs in submit queue */ -+ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, &drb); -+ -+ while (drb) { -+ dmad_dbg("cancel sbt drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x) state(%d)\n", -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, (u32) drb->state); -+ -+ /* Mark DRB state as abort */ -+ drb->state = DMAD_DRB_STATE_ABORT; -+ -+ if (drb->sync) -+ complete_all(drb->sync); -+ -+ dmad_attach_tail(drq->drb_pool, &drq->fre_head, &drq->fre_tail, -+ drb->node); -+ -+ dmad_detach_head(drq->drb_pool, &drq->sbt_head, &drq->sbt_tail, -+ &drb); -+ } -+ -+ /* Detach DRBs in ready queue */ -+ dmad_detach_head(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, &drb); -+ -+ while (drb) { -+ dmad_dbg("cancel rdy drb(%d 0x%08x) addr0(0x%08x) " -+ "addr1(0x%08x) size(0x%08x) state(%d)\n", -+ drb->node, (u32) drb, drb->src_addr, drb->dst_addr, -+ drb->req_cycle, (u32) drb->state); -+ -+ /* Mark DRB state as abort */ -+ drb->state = DMAD_DRB_STATE_ABORT; -+ -+ dmad_attach_tail(drq->drb_pool, &drq->fre_head, &drq->fre_tail, -+ drb->node); -+ -+ /* Detach next submitted DRB (DMA Request Block) from the -+ * DRQ (DMA Request Queue) */ -+ dmad_detach_head(drq->drb_pool, &drq->rdy_head, &drq->rdy_tail, -+ &drb); -+ } -+ -+ drq->state |= DMAD_DRQ_STATE_ABORT; -+ -+ drq->ring_drb = NULL; -+ drq->sw_ptr = 0; -+ drq->sw_p_idx = 0; -+ drq->sw_p_off = 0; -+ -+ spin_unlock_irqrestore(&drq->drb_pool_lock, lock_flags); -+ -+ if ( /*(drq->fre_head == 0) && */ (drq->flags & DMAD_FLAGS_SLEEP_BLOCK)) { -+ complete_all(&drq->drb_alloc_sync); -+ } -+ -+ return 0; -+} -+ -+/** -+ * dmad_cancel_requests - cancel DMA transmission of the given DMA channel -+ * @ch_req : [in] Reference to the DMA request descriptor structure -+ * @shutdown : [in] Non-zero to force a immediate channel shutdown -+ * @return : 0 if success, non-zero if any error -+ * -+ * Stop the DMA transmission and cancel all submitted requests of the given -+ * DMA channel. -+ */ -+int dmad_drain_requests(dmad_chreq * ch_req, u8 shutdown) -+{ -+ dmad_dbg("%s()\n", __func__); -+ -+ if (ch_req == NULL) { -+ dmad_err("null ch_req!\n"); -+ return -EFAULT; -+ } -+ -+ return dmad_channel_drain(ch_req->controller, ch_req->drq, shutdown); -+} -+ -+EXPORT_SYMBOL_GPL(dmad_drain_requests); -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ -+/** -+ * dmad_probe_irq_source - probe DMA channel who asserts the shared sw-irq line -+ * @return : The channel number which asserts the shared sw-irq line -+ * -+ * Probe DMA channel who asserts the shared sw-irq line. -+ */ -+int dmad_probe_irq_source_ahb(void) -+{ -+ int channel; /* interrupt channel number */ -+ -+ /* todo: spin_lock */ -+ -+ /* - Check DMA status register to get channel number */ -+ for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) { -+ if (getbl(channel, DMAC_INT_TC)) -+ return channel; -+ } -+ -+ /* Perform DMA error checking if no valid channel was found who -+ * assert the finish signal. */ -+ for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) { -+ if (getbl(channel, DMAC_INT_ERRABT)) -+ return channel; -+ if (getbl(channel << DMAC_INT_ABT_SHIFT, DMAC_INT_ERRABT)) -+ return channel; -+ } -+ -+ /* todo: spin_unlock */ -+ -+ return -EFAULT; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_probe_irq_source_ahb); -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+int dmad_probe_irq_source_apb(void) -+{ -+ int channel; /* interrupt channel number */ -+ -+ /* todo: spin_lock */ -+ -+ /* Check DMA status register to get channel number */ -+ for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) { -+ if (getbl(APBBR_DMA_FINTST_BIT, APBBR_DMA_BASE_CH(channel) + -+ APBBR_DMA_CMD_OFFSET)) -+ return channel; -+ } -+ -+ /* Perform DMA error checking if no valid channel was found who -+ * assert the finish signal. */ -+ for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) { -+ if (getbl(APBBR_DMA_ERRINTST_BIT, APBBR_DMA_BASE_CH(channel) + -+ APBBR_DMA_CMD_OFFSET)) -+ return channel; -+ } -+ -+ /* todo: spin_unlock */ -+ -+ return -EFAULT; -+} -+ -+EXPORT_SYMBOL_GPL(dmad_probe_irq_source_apb); -+ -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+/** -+ * dmad_module_init - dma module-init function -+ * @return : 0 if success, non-zero if any error -+ */ -+int __init dmad_module_init(void) -+{ -+ int err = 0; -+ dmad_dbg("%s() >>\n", __func__); -+ -+ /* clear device struct since the module may be load/unload many times */ -+ memset(&dmad, 0, sizeof(dmad)); -+ -+ dmad.drq_pool = -+ kmalloc((DMAD_AHB_MAX_CHANNELS + -+ DMAD_APB_MAX_CHANNELS) * sizeof(dmad_drq), GFP_KERNEL); -+ if (dmad.drq_pool == NULL) { -+ dmad_err("%s() failed to allocate drb pool!\n", __func__); -+ return -ENOMEM; -+ } -+ -+ memset(dmad.drq_pool, 0, -+ (DMAD_AHB_MAX_CHANNELS + DMAD_APB_MAX_CHANNELS) * -+ sizeof(dmad_drq)); -+ -+ spin_lock_init(&dmad.drq_pool_lock); -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ dmad.ahb_drq_pool = dmad.drq_pool; -+ if (unlikely(!request_region(DMAC_BASE, SZ_1K, "AHB DMAC"))) { -+ dmad_err("Cannot reserve AHB DMAC I/O region\n"); -+ err = -EBUSY; -+ } -+#endif -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ dmad.apb_drq_pool = &dmad.drq_pool[DMAD_AHB_MAX_CHANNELS]; -+ if (unlikely(!request_region(APBBR_BASE, SZ_1K, "APB DMAC"))) { -+ dmad_err("Cannot reserve APB DMAC I/O region\n"); -+ err = -EBUSY; -+ } -+#endif -+ -+ dmad_dbg("DMA module init result: (%d)\n", err); -+ dmad_dbg(" AHB channels: %d; APB channels %d; " -+ "DRBs per channel: %d\n", -+ DMAC_MAX_CHANNELS, APBBR_DMA_MAX_CHANNELS, DMAD_DRB_POOL_SIZE); -+ -+ dmad_dbg("%s() return code (%d) <<\n", __func__, err); -+ return err; -+} -+ -+/** -+ * dmad_module_init - dma module clean up function -+ */ -+void __exit dmad_module_exit(void) -+{ -+ dmad_drq *drq; -+ u32 channel; -+ -+ dmad_dbg("%s() >>\n", __func__); -+ -+ spin_lock(&dmad.drq_pool_lock); -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ /* cancel existing requests and unregister interrupt handler */ -+ for (channel = 0; channel < DMAD_AHB_MAX_CHANNELS; ++channel) { -+ -+ /* shutdown dma requests */ -+ drq = (dmad_drq *) & dmad.ahb_drq_pool[channel]; -+ -+ if ((drq->state & DMAD_DRQ_STATE_READY) != 0) -+ dmad_channel_drain(DMAD_DMAC_AHB_CORE, drq, 1); -+ -+ /* free registered irq handlers */ -+ free_irq(ahb_irqs[channel], (void *)(channel + 1)); -+ } -+#endif -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ /* cancel existing requests and unregister interrupt handler */ -+ for (channel = 0; channel < DMAD_APB_MAX_CHANNELS; ++channel) { -+ -+ /* shutdown dma requests */ -+ drq = (dmad_drq *) & dmad.apb_drq_pool[channel]; -+ -+ if ((drq->state & DMAD_DRQ_STATE_READY) != 0) -+ dmad_channel_drain(DMAD_DMAC_APB_CORE, drq, 1); -+ -+ /* free registered irq handlers */ -+ free_irq(apb_irqs[channel], (void *)(channel + 1)); -+ } -+#endif -+ spin_unlock(&dmad.drq_pool_lock); -+ -+ if (dmad.drq_pool) -+ kfree(dmad.drq_pool); -+ memset(&dmad, 0, sizeof(dmad)); -+ -+ /* release I/O space */ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ release_region(DMAC_BASE, SZ_1K); -+#endif /*CONFIG_PLATFORM_AHBDMA */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ release_region(APBBR_BASE, SZ_1K); -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+ dmad_dbg("DMA module unloaded!\n"); -+} -+ -+#ifndef MODULE -+arch_initcall(dmad_module_init); -+#else -+module_init(dmad_module_init); -+module_exit(dmad_module_exit); -+#endif -+ -+#endif /* CONFIG_PLATFORM_AHBDMA || CONFIG_PLATFORM_APBDMA */ -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/dmad_intc.c linux-3.4.113/arch/nds32/platforms/dmad_intc.c ---- linux-3.4.113.orig/arch/nds32/platforms/dmad_intc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/dmad_intc.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,124 @@ -+/* -+ * linux/arch/armnommu/mach-faraday/platform-a320/apb_intc.c -+ * -+ * Faraday AHB DMA Interrupt Process Driver Implementation -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * 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. -+ * -+ * -+ * ChangeLog -+ * -+ * Peter Liao 09/28/2005 Created -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+extern int dmad_probe_irq_source_ahb(void); -+ -+void AHBDMA_irq_rounter(unsigned int irq, struct irq_desc *desc) -+{ -+ int ahb_irq; -+ struct irq_desc *ahb_desc; -+ struct irq_data data; -+ data.irq = irq; -+ -+ raw_spin_lock(&desc->lock); -+ desc->irq_data.chip->irq_mask(&data); -+ desc->irq_data.chip->irq_ack(&data); -+ -+ ahb_irq = dmad_probe_irq_source_ahb(); -+ if (ahb_irq >= 0) { -+ ahb_irq += DMAC_FTDMAC020_IRQ0; -+ ahb_desc = irq_desc + ahb_irq; -+ -+ raw_spin_unlock(&desc->lock); -+ ahb_desc->handle_irq(ahb_irq, ahb_desc); -+ raw_spin_lock(&desc->lock); -+ } -+ -+ desc->irq_data.chip->irq_unmask(&data); -+ raw_spin_unlock(&desc->lock); -+} -+ -+int __init intc_ftdmac020_init_irq(void) -+{ -+ int i; -+ -+ /* Register all IRQ */ -+ for (i = DMAC_FTDMAC020_IRQ0; -+ i < DMAC_FTDMAC020_IRQ0 + DMAC_FTDMAC020_IRQ_COUNT; i++) { -+ // level trigger -+ irq_set_chip(i, &dummy_irq_chip); -+ irq_set_handler(i, handle_simple_irq); -+ } -+ irq_set_chained_handler(PLATFORM_AHBDMA_IRQ, AHBDMA_irq_rounter); -+ -+ return 0; -+} -+ -+arch_initcall(intc_ftdmac020_init_irq); -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+extern int dmad_probe_irq_source_apb(void); -+ -+void APBDMA_irq_rounter(unsigned int irq, struct irq_desc *desc) -+{ -+ int apb_irq; -+ struct irq_desc *apb_desc; -+ struct irq_data data; -+ data.irq = irq; -+ -+ raw_spin_lock(&desc->lock); -+ -+ //mask_ack_irq(desc, irq); -+ desc->irq_data.chip->irq_mask(&data); -+ desc->irq_data.chip->irq_ack(&data); -+ -+ apb_irq = dmad_probe_irq_source_apb(); -+ //printk(KERN_INFO "irq (%d) ch(%d)\n", irq, apb_irq); -+ -+ if (apb_irq >= 0) { -+ apb_irq += APBBRG_FTAPBBRG020S_0_IRQ0; -+ apb_desc = irq_desc + apb_irq; -+ -+ raw_spin_unlock(&desc->lock); -+ apb_desc->handle_irq(irq, apb_desc); -+ raw_spin_lock(&desc->lock); -+ } -+ -+ desc->irq_data.chip->irq_unmask(&data); -+ raw_spin_unlock(&desc->lock); -+} -+ -+int __init intc_ftapbbrg020s_init_irq(void) -+{ -+ int i; -+ -+ /* Register all IRQ */ -+ for (i = APBBRG_FTAPBBRG020S_0_IRQ0; -+ i < APBBRG_FTAPBBRG020S_0_IRQ0 + APBBRG_FTAPBBRG020S_IRQ_COUNT; -+ i++) { -+ // level trigger -+ irq_set_chip(i, &dummy_irq_chip); -+ irq_set_handler(i, handle_simple_irq); -+ } -+ -+ irq_set_chained_handler(PLATFORM_APBDMA_IRQ, APBDMA_irq_rounter); -+ -+ return 0; -+} -+ -+arch_initcall(intc_ftapbbrg020s_init_irq); -+#endif /* CONFIG_PLATFORM_APBDMA */ -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/ftpci.c linux-3.4.113/arch/nds32/platforms/ftpci.c ---- linux-3.4.113.orig/arch/nds32/platforms/ftpci.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/ftpci.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,497 @@ -+/* -+ * linux/arch/nds32/platforms/ftpci.c -+ * -+ * Faraday FTPCI100 PCI Bridge Controller Device Driver Implementation -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * -+ * ChangeLog -+ * -+ * Peter Liao 09/28/2005 Created. -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define IPMODULE PCIC -+#define IPNAME FTPCI100 -+ -+#define DEBUGFPCI -+#undef DEBUGFPCI -+ -+#ifdef DEBUGFPCI -+#define DBGFPCI(x...) printk(x) -+#else -+#define DBGFPCI(x...) -+#endif -+#define FPCI_VA_BASE IP_VA_BASE(0) -+#define FTPCI_PCI_BRIDGE_VENID PCI_BRIDGE_VENID -+#define FPCI_IO_VA_BASE PCIIO_VA_BASE -+#define FPCI_IO_PA_BASE PCIIO_PA_BASE -+#define FPCI_IO_VA_END PCIIO_VA_LIMIT -+#define FPCI_MEM_VA_BASE PCIMEM_VA_BASE -+#define FPCI_MEM_PA_BASE PCIMEM_PA_BASE -+#define FPCI_MEM_VA_END PCIMEM_VA_LIMIT -+#define FPCI_MEM_PA_END (PCIMEM_PA_BASE + SZ_256M) -+ -+// -------------------------------------------------------------------- -+// AHB Control Register -+// -------------------------------------------------------------------- -+#define FTPCI_IOSIZE_REG 0x0 -+#define FTPCI_PROT_REG 0x4 -+#define FTPCI_CTRL_REG 0x8 -+#define FTPCI_ERREN_REG 0xc -+#define FTPCI_SOFTRST_REG 0x10 -+#define FTPCI_EN64_REG 0x14 -+#define FTPCI_ADDRH32_REG 0x18 -+#define FTPCI_CFG_ADR_REG 0x28 -+#define FTPCI_CFG_DATA_REG 0x2c -+ -+// -------------------------------------------------------------------- -+// FTPCI_IOSIZE_REG's constant definitions -+// -------------------------------------------------------------------- -+#define FTPCI_BASE_IO_SIZE_1M 0x0 -+#define FTPCI_BASE_IO_SIZE_2M 0x1 -+#define FTPCI_BASE_IO_SIZE_4M 0x2 -+#define FTPCI_BASE_IO_SIZE_8M 0x3 -+#define FTPCI_BASE_IO_SIZE_16M 0x4 -+#define FTPCI_BASE_IO_SIZE_32M 0x5 -+#define FTPCI_BASE_IO_SIZE_64M 0x6 -+#define FTPCI_BASE_IO_SIZE_128M 0x7 -+#define FTPCI_BASE_IO_SIZE_256M 0x8 -+#define FTPCI_BASE_IO_SIZE_512M 0x9 -+#define FTPCI_BASE_IO_SIZE_1G 0xa -+#define FTPCI_BASE_IO_SIZE_2G 0xb -+ -+// -------------------------------------------------------------------- -+// PCI Configuration Register -+// -------------------------------------------------------------------- -+#define PCI_INT_MASK 0x4c -+#define PCI_MEM_BASE_SIZE1 0x50 -+#define PCI_MEM_BASE_SIZE2 0x54 -+#define PCI_MEM_BASE_SIZE3 0x58 -+ -+// -------------------------------------------------------------------- -+// PCI_INT_MASK's bit definitions -+// -------------------------------------------------------------------- -+#define PCI_INTA_ENABLE (1U<<22) -+#define PCI_INTB_ENABLE (1U<<23) -+#define PCI_INTC_ENABLE (1U<<24) -+#define PCI_INTD_ENABLE (1U<<25) -+ -+// -------------------------------------------------------------------- -+// PCI_MEM_BASE_SIZE1's constant definitions -+// -------------------------------------------------------------------- -+#define FTPCI_BASE_ADR_SIZE_1MB (PHYS_OFFSET | (0x0<<16)) -+#define FTPCI_BASE_ADR_SIZE_2MB (PHYS_OFFSET | (0x1<<16)) -+#define FTPCI_BASE_ADR_SIZE_4MB (PHYS_OFFSET | (0x2<<16)) -+#define FTPCI_BASE_ADR_SIZE_8MB (PHYS_OFFSET | (0x3<<16)) -+#define FTPCI_BASE_ADR_SIZE_16MB (PHYS_OFFSET | (0x4<<16)) -+#define FTPCI_BASE_ADR_SIZE_32MB (PHYS_OFFSET | (0x5<<16)) -+#define FTPCI_BASE_ADR_SIZE_64MB (PHYS_OFFSET | (0x6<<16)) -+#define FTPCI_BASE_ADR_SIZE_128MB (PHYS_OFFSET | (0x7<<16)) -+#define FTPCI_BASE_ADR_SIZE_256MB (PHYS_OFFSET | (0x8<<16)) -+#define FTPCI_BASE_ADR_SIZE_512MB (PHYS_OFFSET | (0x9<<16)) -+#define FTPCI_BASE_ADR_SIZE_1GB (PHYS_OFFSET | (0xa<<16)) -+#define FTPCI_BASE_ADR_SIZE_2GB (PHYS_OFFSET | (0xb<<16)) -+ -+#define CONFIG_CMD(bus, device_fn, where) (0x80000000 | (bus << 16) | (device_fn << 8) | (where & ~3) ) -+ -+struct pci_dev *pci_bridge = NULL; -+static unsigned int pci_config_addr; -+static unsigned int pci_config_data; -+int ftpci_probed = 0; -+ -+static struct resource pcic_resource = { -+ .name = "Faradat PCIC", -+ .start = IP_VA_BASE(0), -+ .end = IP_VA_LIMIT(0), -+}; -+ -+// Luke Lee 03/21/2005 mod begin -+static int ftpci_read_config_byte(struct pci_bus *bus, unsigned int devfn, -+ int where, u8 * val) -+{ -+ u32 v; -+ unsigned int shift; -+ -+ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); -+ v = inl(pci_config_data); -+ shift = (where & 0x3) * 8; -+ *val = (v >> shift) & 0xff; -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int ftpci_read_config_word(struct pci_bus *bus, unsigned int devfn, -+ int where, u16 * val) -+{ -+ u32 v; -+ unsigned int shift; -+ -+ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); -+ v = inl(pci_config_data); -+ shift = (where & 0x3) * 8; -+ *val = (v >> shift) & 0xffff; -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int ftpci_read_config_dword(struct pci_bus *bus, unsigned int devfn, -+ int where, u32 * val) -+{ -+ u32 v; -+ -+ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); -+ v = inl(pci_config_data); -+ *val = v; -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int ftpci_write_config_byte(struct pci_bus *bus, unsigned int devfn, -+ int where, u8 val) -+{ -+ u32 org_val; -+ unsigned int shift; -+ -+ shift = (where & 0x3) * 8; -+ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); -+ org_val = inl(pci_config_data); -+ org_val = (org_val & ~(0xff << shift)) | ((u32) val << shift); -+ outl(org_val, pci_config_data); -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int ftpci_write_config_word(struct pci_bus *bus, unsigned int devfn, -+ int where, u16 val) -+{ -+ u32 org_val; -+ unsigned int shift; -+ -+ shift = (where & 0x3) * 8; -+ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); -+ org_val = inl(pci_config_data); -+ org_val = (org_val & ~(0xffff << shift)) | ((u32) val << shift); -+ outl(org_val, pci_config_data); -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+static int ftpci_write_config_dword(struct pci_bus *bus, unsigned int devfn, -+ int where, u32 val) -+{ -+ outl(CONFIG_CMD(bus->number, devfn, where), pci_config_addr); -+ outl(val, pci_config_data); -+ return PCIBIOS_SUCCESSFUL; -+} -+ -+// Luke Lee 03/21/2005 mod end -+ -+// Luke Lee 03/21/2005 ins begin -+static int ftpci_read_config(struct pci_bus *bus, unsigned int devfn, int where, -+ int size, u32 * val) -+{ -+ int r; -+ switch (size) { -+ case 1: -+ r = ftpci_read_config_byte(bus, devfn, where, (u8 *) val); // Luke Lee TOFIX 03/22/2005 : convert to (u8*) -- beware of endian ! -+ break; -+ case 2: -+ r = ftpci_read_config_word(bus, devfn, where, (u16 *) val); // Luke Lee TOFIX 03/22/2005 : convert to (u16*) -- beware of endian ! -+ break; -+ -+ default: -+ r = ftpci_read_config_dword(bus, devfn, where, val); -+ break; -+ } -+ -+ return r; -+} -+ -+static int ftpci_write_config(struct pci_bus *bus, unsigned int devfn, -+ int where, int size, u32 val) -+{ -+ int r; -+ switch (size) { -+ case 1: -+ r = ftpci_write_config_byte(bus, devfn, where, val); -+ break; -+ case 2: -+ r = ftpci_write_config_word(bus, devfn, where, val); -+ break; -+ -+ case 4: -+ r = ftpci_write_config_dword(bus, devfn, where, val); -+ break; -+ default: -+ printk("Invalid size for ftpci_write()\n"); -+ r = PCIBIOS_FUNC_NOT_SUPPORTED; // Luke Lee 03/23/2005 ins 1 -+ } -+ -+ return r; -+} -+ -+// Luke Lee 03/21/2005 ins end -+ -+static struct pci_ops ftpci_ops = { -+ // Luke Lee 03/21/2005 mod begin -+ .read = ftpci_read_config, -+ .write = ftpci_write_config, -+ // Luke Lee 03/21/2005 mod end -+}; -+ -+/* using virtual address for pci_resource_start() function*/ -+static struct resource pci_io = { -+ .name = "Faraday PCI I/O Space", -+ .start = FPCI_IO_VA_BASE, -+ .end = FPCI_IO_VA_END, -+ .flags = IORESOURCE_IO, -+}; -+ -+/* using physical address for memory resource*/ -+static struct resource pci_mem = { -+ .name = "Faraday PCI non-prefetchable Memory Space", -+ .start = FPCI_MEM_PA_BASE, -+ .end = FPCI_MEM_PA_END, -+ .flags = IORESOURCE_MEM, -+}; -+ -+// Luke Lee 03/23/2005 unrem 1 rem 1 -+int __init ftpci_setup_resource(struct resource **resource) -+{ -+ DBGFPCI("PCI I/O space from %08lX to %08lX\n", pci_io.start, -+ pci_io.end); -+ DBGFPCI("PCI Memory space from %08lX to %08lX\n", pci_mem.start, -+ pci_mem.end); -+ if (request_resource(&ioport_resource, &pci_io)) { -+ printk(KERN_ERR "PCI: unable to allocate io region\n"); -+ return -EBUSY; // Luke Lee 03/23/2005 unrem 1 -+ } -+ if (request_resource(&iomem_resource, &pci_mem)) { -+ printk(KERN_ERR "PCI: unable to allocate non-prefetchable " -+ "memory region\n"); -+ return -EBUSY; // Luke Lee 03/23/2005 unrem 1 -+ } -+ -+ /* -+ * bus->resource[0] is the IO resource for this bus -+ * bus->resource[1] is the mem resource for this bus -+ * bus->resource[2] is the prefetch mem resource for this bus -+ */ -+ -+ resource[0] = &pci_io; -+ resource[1] = &pci_mem; -+ resource[2] = NULL; -+ -+ return 1; // Luke Lee 03/23/2005 unrem 1 -+} -+ -+int ftpci_get_irq(void) -+{ -+ unsigned int status; -+ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, &status); // Luke Lee 03/22/2005 mod 1 -+ DBGFPCI("ftpci_get_irq,status=0x%x\n", status); -+ status = (status >> 28); -+ if (status & 0x1) -+ return 0; -+ if (status & 0x2) -+ return 1; -+ if (status & 0x4) -+ return 2; -+ if (status & 0x8) -+ return 3; -+ return -1; -+} -+ -+void ftpci_clear_irq(unsigned int irq) -+{ -+ //int i; -+ unsigned int status; -+ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, &status); // Luke Lee 03/22/2005 mod 1 -+ if (irq == 0) -+ status = (status & 0xfffffff) | ((0x1) << 28); -+ else if (irq == 1) -+ status = (status & 0xfffffff) | ((0x2) << 28); -+ else if (irq == 2) -+ status = (status & 0xfffffff) | ((0x4) << 28); -+ else if (irq == 3) -+ status = (status & 0xfffffff) | ((0x8) << 28); -+ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, 0x4c, status); // Luke Lee 03/22/2005 mod 1 -+} -+ -+void ftpci_unmask_irq(unsigned int irq) -+{ -+ u32 val; -+ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, -+ PCI_INT_MASK, &val); -+ val |= (PCI_INTA_ENABLE << irq); -+ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, -+ PCI_INT_MASK, val); -+} -+ -+void ftpci_mask_irq(unsigned int irq) -+{ -+ u32 val; -+ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, -+ PCI_INT_MASK, &val); -+ val &= ~(PCI_INTA_ENABLE << irq); -+ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, -+ PCI_INT_MASK, val); -+} -+ -+static int ftpci_probe(unsigned int addr_p) -+{ -+ unsigned int *addr = (unsigned int *)addr_p; -+ *(volatile unsigned int *)addr = 0x80000000; -+ if (*(volatile unsigned int *)addr == 0x80000000) { -+ DBGFPCI("Faraday FPCI bridge probed ok\n"); -+ ftpci_probed = 1; -+ } else { -+ ftpci_probed = 0; -+ } -+ *(volatile unsigned int *)addr = 0x0; -+ return ftpci_probed; -+} -+ -+void __init ftpci_preinit(void /**sysdata*/ ) // Luke Lee 03/22/2005 mod 1 -+{ -+ DBGFPCI("ftpci_preinit()\n\r"); -+ -+#ifdef CONFIG_PLAT_AG101 -+ /* Walk around for A321 but remove after leopard pci */ -+ *(volatile unsigned long *)(FPCI_VA_BASE + 0x8) = 0x10; -+#endif -+ -+ pci_config_addr = FPCI_VA_BASE + FTPCI_CFG_ADR_REG; -+ pci_config_data = FPCI_VA_BASE + FTPCI_CFG_DATA_REG; -+ DBGFPCI("Config addr is %08X, data port is %08X\n", -+ (int)pci_config_addr, (int)pci_config_data); -+ -+ if (!ftpci_probe(pci_config_addr)) -+ return; -+} -+ -+void ftpci_postinit(void /**sysdata*/ ) -+{ -+ u32 val; -+ DBGFPCI("ftpci_postinit()\n\r"); -+ pci_bridge = pci_get_device(PCI_BRIDGE_VENID, PCI_BRIDGE_DEVID, NULL); -+ if (pci_bridge == NULL) -+ return; -+ // Enable the Interrupt Mask (INTA/INTB/INTC/INTD) -+ ftpci_read_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_INT_MASK, &val); // Luke Lee 03/22/2005 mod 1 -+ val |= -+ (PCI_INTA_ENABLE | PCI_INTB_ENABLE | PCI_INTC_ENABLE | -+ PCI_INTD_ENABLE); -+ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_INT_MASK, val); // Luke Lee 03/22/2005 mod 1 -+ -+ // Write DMA Start Address/Size Data to the Bridge configuration space -+ ftpci_write_config_dword(pci_bridge->bus, pci_bridge->devfn, PCI_MEM_BASE_SIZE1, FTPCI_BASE_ADR_SIZE_1GB); // Luke Lee 03/22/2005 mod 1 -+ DBGFPCI("%s: Post init ok\n", __func__); -+} -+ -+/* -+ * This routine handles multiple bridges. -+ */ -+static u8 __init fpci_swizzle(struct pci_dev *dev, u8 * pinp) -+{ -+ // If there are one more bridges on our platfrom, we need to implement this function. -+ DBGFPCI("a320_swizzle(%X,%X)\n\r", (unsigned)dev, (unsigned)pinp); -+ return 0; -+} -+ -+static int __init fpci_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -+{ -+ DBGFPCI("a320_map_irq,slot=%d pin=%d\n", PCI_SLOT(dev->devfn), pin); -+ switch ((PCI_SLOT(dev->devfn) + pin - 8 - 1) % 4) { -+ case 0: -+ return IP_IRQ0(0); -+ case 1: -+ return IP_IRQ1(0); -+ case 2: -+ return IP_IRQ2(0); -+ case 3: -+ return IP_IRQ3(0); -+ default: -+ printk(KERN_ERR "Not Support Slot %d\n", slot); -+ break; -+ } -+ return -1; -+} -+ -+int __init ftpci_setup(int nr, struct pci_sys_data *sys) -+{ -+ int ret = 0; -+ if (nr == 0) { -+ ret = ftpci_setup_resource(sys->resource); -+// sys->mem_offset = FPCI_MEM_VA_BASE - FPCI_MEM_PA_BASE; -+ sys->mem_offset = 0; -+ sys->io_offset = FPCI_IO_VA_BASE - FPCI_IO_PA_BASE; -+ } -+ return ret; -+} -+ -+static struct pci_bus *__devinit ftpci_scan_bus(int nr, -+ struct pci_sys_data *sys) -+{ -+ return pci_scan_bus(sys->busnr, &ftpci_ops, sys); -+} -+ -+static struct hw_pci a320_pci __initdata = { -+ .swizzle = fpci_swizzle, -+ .map_irq = fpci_map_irq, -+ .setup = ftpci_setup, -+ .nr_controllers = 1, -+ .scan = ftpci_scan_bus, -+ .preinit = ftpci_preinit, /* The first called init function */ -+ .postinit = ftpci_postinit, /* It is called after hw init and scanned PCI bus */ -+}; -+ -+static int __init fpci_init(void) -+{ -+#ifdef MODULE -+ printk(KERN_INFO "Faraday PCI driver Init"); -+#endif -+ printk(KERN_DEBUG "Init A321 PCI bridge controller\n"); -+ /* Register I/O address range of this PCI Bridge Controller */ -+ DBGFPCI("Name:%s, Base=%lX, End=%lX\n", pcic_resource.name, -+ pcic_resource.start, pcic_resource.end); -+ request_resource(&ioport_resource, &pcic_resource); -+ pci_common_init(&a320_pci); -+ return 0; -+} -+ -+subsys_initcall(fpci_init); -+ -+EXPORT_SYMBOL(ftpci_probed); -+EXPORT_SYMBOL(ftpci_clear_irq); -+EXPORT_SYMBOL(ftpci_get_irq); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/intc.c linux-3.4.113/arch/nds32/platforms/intc.c ---- linux-3.4.113.orig/arch/nds32/platforms/intc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/intc.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,257 @@ -+/* -+ * linux/arch/nds32/platforms/intc.c -+ * -+ * Faraday FTINTC010 Master Interrupt Controller Device Driver Implementation -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * 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 -+ * -+ * Note -+ * -+ * This program implements only the master INTC of the platform. Slave INTCs must -+ * be initialized by themselves. -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/14/2005 Created. -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define IPMODULE INTC -+#define IPNAME FTINTC010 -+ -+/* -+ * Edge trigger IRQ chip methods -+ */ -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+spinlock_t irq_chip_lock; -+#endif -+ -+static void intc_ftintc010_ack_irq(struct irq_data *data) -+{ -+ unsigned int tmp; -+ -+ // ack and disable -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_lock_irq(&irq_chip_lock); -+#endif -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG) = 1 << data->irq; -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG); -+ -+ if (!(tmp & (1UL << data->irq))) { /* level trigger */ -+ -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &= -+ ~(1 << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); -+ } -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_unlock_irq(&irq_chip_lock); -+#endif -+} -+ -+static void intc_ftintc010_mask_irq(struct irq_data *data) -+{ -+ unsigned int tmp; -+ -+ // disable -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_lock_irq(&irq_chip_lock); -+#endif -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &= -+ ~(1 << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_unlock_irq(&irq_chip_lock); -+#endif -+} -+ -+static void intc_ftintc010_mask_ack_irq(struct irq_data *data) -+{ -+ unsigned int tmp; -+ -+ // disable -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_lock_irq(&irq_chip_lock); -+#endif -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) &= -+ ~(1 << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); -+ -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG) = 1 << data->irq; -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_CLEAR_REG); -+ -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_unlock_irq(&irq_chip_lock); -+#endif -+} -+ -+static void intc_ftintc010_unmask_irq(struct irq_data *data) -+{ -+ unsigned int tmp; -+ -+ // enable -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_lock_irq(&irq_chip_lock); -+#endif -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG) |= 1 << data->irq; -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MASK_REG); -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_unlock_irq(&irq_chip_lock); -+#endif -+} -+ -+static int intc_ftintc010_set_type(struct irq_data *data, -+ unsigned int flow_type) -+{ -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_lock_irq(&irq_chip_lock); -+#endif -+ /* -+ * IRQ Trigger Mode Register 1: edge -+ * IRQ Trigger Level Register 1: active high -+ */ -+ -+ int tmp; -+ -+ if (flow_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW)) { -+ -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG) &= -+ ~(1UL << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG); -+ } -+ -+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_HIGH)) { -+ -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG) |= -+ (1UL << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_LEVEL_REG); -+ } -+ -+ if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) { -+ -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG) |= -+ (1UL << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG); -+ (irq_desc + data->irq)->handle_irq = handle_edge_irq; -+ } -+ -+ if (flow_type & (IRQF_TRIGGER_HIGH | IRQF_TRIGGER_LOW)) { -+ -+ *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG) &= -+ ~(1UL << data->irq); -+ tmp = *(volatile unsigned *)(IP_VA_BASE(0) + IRQ_MODE_REG); -+ (irq_desc + data->irq)->handle_irq = handle_level_irq; -+ } -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_unlock_irq(&irq_chip_lock); -+#endif -+ return 0; -+} -+ -+static struct irq_chip intc_ftintc010_chip = { -+ -+ .irq_ack = intc_ftintc010_ack_irq, -+ .irq_mask = intc_ftintc010_mask_irq, -+ .irq_mask_ack = intc_ftintc010_mask_ack_irq, -+ .irq_unmask = intc_ftintc010_unmask_irq, -+ .irq_set_type = intc_ftintc010_set_type, -+}; -+ -+static struct resource intc_resource = { -+ -+ .name = "Main interrupt controller", -+ .start = IP_VA_BASE(0), -+ .end = IP_VA_BASE(0) + IP_VA_SIZE(0), -+}; -+ -+/* -+ * Initialization of master interrupt controller, after this INTC is -+ * enabled, the rest of Linux initialization codes can then be completed. -+ * For example, timer interrupts and UART interrupts must be enabled during -+ * the boot process. -+ */ -+void __init intc_ftintc010_init_irq(void) -+{ -+ int i, edge; -+ -+#if defined(CONFIG_SMP) && defined(CONFIG_IRQ_PER_CPU) -+ spin_lock_init(&irq_chip_lock); -+#endif -+ /* Initialize the INTC */ -+ outl(0x00000000, IP_VA_BASE(0) + IRQ_MASK_REG); -+ outl(0x00000000, IP_VA_BASE(0) + FIQ_MASK_REG); -+ outl(0xffffffff, IP_VA_BASE(0) + IRQ_CLEAR_REG); -+ outl(0xffffffff, IP_VA_BASE(0) + FIQ_CLEAR_REG); -+ outl(PLATFORM_IRQ_TRIGGER_MODE, IP_VA_BASE(0) + IRQ_MODE_REG); -+ /* FTINTC010: bit 0=active high or rising edge, 1=active low or falling edge. */ -+ outl(PLATFORM_IRQ_TRIGGER_LEVEL, IP_VA_BASE(0) + IRQ_LEVEL_REG); -+ -+ /* Register all IRQ */ -+ for (i = PLATFORM_IRQ_BASE, edge = 1; -+ i < PLATFORM_IRQ_BASE + PLATFORM_IRQ_TOTALCOUNT; i++, edge <<= 1) { -+ -+ irq_set_chip(i, &intc_ftintc010_chip); -+ -+ if (PLATFORM_IRQ_TRIGGER_MODE & edge) /* edge trigger */ -+ irq_set_handler(i, handle_edge_irq); -+ -+ else /* level trigger */ -+ irq_set_handler(i, handle_level_irq); -+ } -+ -+ /* Register I/O address range of this INTC */ -+ request_resource(&ioport_resource, &intc_resource); -+ -+} -+ -+unsigned int get_IntSrc(void) -+{ -+ unsigned int irq_status, irq = 31; -+ -+ irq_status = inl(IP_VA_BASE(0) + IRQ_STATUS_REG); -+ if (irq_status == 0) -+ return 32; -+ if (irq_status & 0x0000ffff) { -+ irq -= 16; -+ irq_status <<= 16; -+ } -+ if (irq_status & 0x00ff0000) { -+ irq -= 8; -+ irq_status <<= 8; -+ } -+ if (irq_status & 0x0f000000) { -+ irq -= 4; -+ irq_status <<= 4; -+ } -+ if (irq_status & 0x30000000) { -+ irq -= 2; -+ irq_status <<= 2; -+ } -+ if (irq_status & 0x40000000) { -+ irq -= 1; -+ } -+ return irq; -+} -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/Kconfig linux-3.4.113/arch/nds32/platforms/Kconfig ---- linux-3.4.113.orig/arch/nds32/platforms/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/Kconfig 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,122 @@ -+choice -+ prompt "platform type" -+ default PLAT_AG101P -+ -+config PLAT_VEP -+ bool "vep platform" -+ select CPU_CUSTOM -+ select PLATFORM_INTC -+ -+config PLAT_AG101 -+ bool "ag101 platform" -+ select CPU_N1213 -+ select CPU_N1213_43U1HA0 -+ select PLATFORM_INTC -+ -+config PLAT_AG102 -+ bool "ag102 platform" -+ select CPU_N1233F -+ select PLATFORM_AMIC -+ -+config PLAT_AG101P -+ bool "ag101p platform" -+ select CPU_CUSTOM -+ select PLATFORM_INTC if !IVIC -+ select PLATFORM_NOINTC if IVIC -+ -+config PLAT_QEMU -+ bool "qemu platform" -+ select CPU_CUSTOM -+ select PLATFORM_INTC -+endchoice -+ -+config PLATFORM_NOINTC -+ def_bool n -+ depends on PLAT_AG101P -+ -+config PLATFORM_INTC -+ def_bool n -+ depends on !PLAT_AG102 -+ -+config PLATFORM_AMIC -+ def_bool n -+ depends on PLAT_AG102 -+ -+config ARCH_WANT_OPTIONAL_GPIOLIB -+ bool "Arch Want Optional GPIOLIB" -+ default y -+ -+if PLAT_VEP -+source "arch/nds32/platforms/vep/Kconfig" -+endif -+ -+if PLAT_AG101 -+source "arch/nds32/platforms/ag101/Kconfig" -+endif -+ -+if PLAT_AG102 -+source "arch/nds32/platforms/ag102/Kconfig" -+endif -+ -+if PLAT_AG101P -+source "arch/nds32/platforms/ag101p/Kconfig" -+endif -+ -+if PLAT_QEMU -+source "arch/nds32/platforms/qemu/Kconfig" -+endif -+ -+menu "Common Platform Options" -+ -+config PLATFORM_AHBDMA -+ tristate "AHB DMA Support" -+ help -+ AHB DMA service API support for other device drivers -+ -+config PLATFORM_APBDMA -+ tristate "APB DMA Support" -+ help -+ AHB DMA service API support for other device drivers -+ -+config SYS_CLK -+ int "AHB System Clock" -+ default 67737600 -+ help -+ Manual setting of AHB clock, must match the jumper setting on -+ the board, or the system time won't be correctly calculated. -+ Notice that even when AUTO_SYS_CLK is ON, this value is still -+ required for adjusting minor time offsets. However, the influence -+ should be within micro-second to nano-second scale. -+ -+config UART_CLK -+ int "UART Clock" -+ default 18432000 -+ help -+ Change the UART clock in case of non-3.6864MHz OSC is used as main -+ clock source, or an external UART clock source is fed from GPIO23. -+ To support external UART clock from GPIO23, set PMU -+ "Multi-Function Port Setting Register" bit #8 (UartClkSel) to 1. -+ This control register can be found at physical address 0x98100028 -+ If this options is changed, please also append "38400" to your -+ kernel command line, e.g.: -+ console=uart,shift,2,io,0xF9820000,38400 -+ Note: For A320, the default UART clock is obtained by = 5 * OSC = -+ 5 * 3.6864MHz = 18.432MHz. -+ -+menu "Memory configuration" -+ -+config SDRAM_SIZE -+ hex "SDRAM Size (hex)" -+ default 4000000 -+ ---help--- -+ RAM size -+ -+config MEMORY_START -+ hex "Physical memory start address" -+ default "0x00000000" -+ ---help--- -+ Physical memory start address, you may modify it if it is porting to -+ a new SoC with different start address. -+endmenu -+ -+endmenu -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/Makefile linux-3.4.113/arch/nds32/platforms/Makefile ---- linux-3.4.113.orig/arch/nds32/platforms/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/Makefile 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,25 @@ -+obj-y := timer.o -+ -+ifdef CONFIG_FUNCTION_TRACER -+CFLAGS_REMOVE_timer.o = -pg -+endif -+ -+obj-$(CONFIG_PLATFORM_NOINTC) += nointc.o -+obj-$(CONFIG_PLATFORM_INTC) += intc.o -+obj-$(CONFIG_PLATFORM_AMIC) += amic.o -+ -+ifeq ("$(CONFIG_PLATFORM_AHBDMA)", "y") -+ obj-y += dmad_intc.o dmad.o -+else -+ ifeq ("$(CONFIG_PLATFORM_APBDMA)", "y") -+ obj-y += dmad_intc.o dmad.o -+ endif -+endif -+ -+obj-$(CONFIG_PCI) += ftpci.o pci_intc.o -+ -+obj-$(CONFIG_PLAT_VEP) += vep/ -+obj-$(CONFIG_PLAT_AG101) += ag101/ -+obj-$(CONFIG_PLAT_AG102) += ag102/ -+obj-$(CONFIG_PLAT_AG101P) += ag101p/ -+obj-$(CONFIG_PLAT_QEMU) += qemu/ -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/nointc.c linux-3.4.113/arch/nds32/platforms/nointc.c ---- linux-3.4.113.orig/arch/nds32/platforms/nointc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/nointc.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,134 @@ -+/* -+ * linux/arch/nds32/platforms/intc.c -+ * -+ * Faraday FTINTC010 Master Interrupt Controller Device Driver Implementation -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ */ -+ -+#include -+ -+static void nointc_ack_irq(struct irq_data *data) -+{ -+ SET_INT_PEND2(1 << data->irq); -+#if 0 -+ asm volatile ("mtsr %0, $INT_PEND2\n\t" -+ "dsb\n\t"::"r" (1 << data->irq)); -+#endif -+#if 0 -+ asm volatile ("mfsr $r6, $INT_MASK2\n\t" -+ "and $r6, $r6,%0\n\t" -+ "mtsr $r6, $INT_MASK2\n\t" -+ "dsb\n\t"::"r" (~(1 << data->irq)):"$r6"); -+#endif -+} -+ -+static void nointc_mask_irq(struct irq_data *data) -+{ -+ unsigned long int_mask2 = GET_INT_MASK2(); -+ SET_INT_MASK2(int_mask2 & (~(1 << data->irq))); -+#if 0 -+ asm volatile ("mfsr $r6, $INT_MASK2\n\t" -+ "and $r6, $r6,%0\n\t" -+ "mtsr $r6, $INT_MASK2\n\t" -+ "dsb\n\t"::"r" (~(1 << data->irq)):"$r6"); -+#endif -+} -+ -+static void nointc_mask_ack_irq(struct irq_data *data) -+{ -+ unsigned long int_mask2 = GET_INT_MASK2(); -+ SET_INT_MASK2(int_mask2 & (~(1 << data->irq))); -+ SET_INT_PEND2(1 << data->irq); -+#if 0 -+ asm volatile ("not $r7, %0\n\t" -+ "mfsr $r6, $INT_MASK2\n\t" -+ "and $r6, $r6, $r7\n\t" -+ "mtsr $r6, $INT_MASK2\n\t" -+ "mtsr %0, $INT_PEND2\n\t" -+ "dsb\n\t"::"r" (1 << data->irq):"$r6", "$r7"); -+#endif -+ -+} -+ -+static void nointc_unmask_irq(struct irq_data *data) -+{ -+ unsigned long int_mask2 = GET_INT_MASK2(); -+ SET_INT_MASK2(int_mask2 | (1 << data->irq)); -+#if 0 -+ asm volatile ("mfsr $r6, $INT_MASK2\n\t" -+ "or $r6, $r6,%0\n\t" -+ "mtsr $r6, $INT_MASK2\n\t" -+ "dsb\n\t"::"r" (1 << data->irq):"$r6"); -+#endif -+} -+ -+static int nointc_set_type(struct irq_data *data, unsigned int flow_type) -+{ -+ printk(KERN_WARNING "interrupt type is not configurable\n"); -+ return 0; -+} -+ -+static struct irq_chip nointc_chip = { -+ -+ .irq_ack = nointc_ack_irq, -+ .irq_mask = nointc_mask_irq, -+ .irq_mask_ack = nointc_mask_ack_irq, -+ .irq_unmask = nointc_unmask_irq, -+ .irq_set_type = nointc_set_type, -+}; -+ -+static unsigned int __initdata nivic_map[6] = { 6, 2, 10, 16, 24, 32 }; -+ -+void __init nointc_init_irq(void) -+{ -+ int i; -+ unsigned long int_trigger_type, int_vec_base, nivic; -+ -+ int_vec_base = GET_IVB(); -+ -+#if 0 -+ asm volatile ("mfsr %0, $IVB\n":"=r" (int_vec_base)); -+#endif -+ -+ if (((int_vec_base & IVB_mskIVIC_VER) >> IVB_offIVIC_VER) == 0) { -+ panic("Unable to use NOINTC option to boot on this cpu\n"); -+ } -+ -+ nivic = (int_vec_base & IVB_mskNIVIC) >> IVB_offNIVIC; -+ if (nivic >= (sizeof nivic_map / sizeof nivic_map[0])) { -+ panic -+ ("The number of input for IVIC Controller is not supported on this cpu\n"); -+ } -+ nivic = nivic_map[nivic]; -+ -+ int_trigger_type = GET_INT_TRIGGER(); -+#if 0 -+ asm volatile ("mfsr %0, $INT_TRIGGER\n":"=r" (int_trigger_type)); -+#endif -+ -+ for (i = 0; i < nivic; i++) { -+ irq_set_chip(i, &nointc_chip); -+ if (int_trigger_type & (1 << i)) -+ /* edge-triggered */ -+ irq_set_handler(i, handle_edge_irq); -+ else -+ /* level-triggered */ -+ irq_set_handler(i, handle_level_irq); -+ } -+} -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/pci_intc.c linux-3.4.113/arch/nds32/platforms/pci_intc.c ---- linux-3.4.113.orig/arch/nds32/platforms/pci_intc.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/pci_intc.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,93 @@ -+/* -+ * linux/arch/nds32/platforms/pci_intc.c -+ * -+ * Faraday PCI Bridge Interrupt Process Driver Implementation -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2008 Andes Technology Corporation -+ * -+ * 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. -+ * -+ * -+ * ChangeLog -+ * -+ * Luke Lee 09/15/2005 Created. -+ * Luke Lee 09/27/2005 Fixed for parent chip registration and notification. -+ * Peter Liao 09/28/2005 Port for PCI IP -+ */ -+ -+#include -+#include -+#include -+#include -+ -+#include -+#include -+ -+#define IPMODULE PCIC -+#define IPNAME FPCI010 -+ -+/* -+ * Level trigger IRQ chip methods -+ */ -+ -+static void intc_ftpci100_level_ack_irq(unsigned int irq) -+{ -+ ftpci_clear_irq(irq - PLATFORM_PCI_IRQ_BASE); -+} -+ -+static void intc_ftpci100_level_mask_irq(unsigned int irq) -+{ -+ ftpci_mask_irq(irq - PLATFORM_PCI_IRQ_BASE); -+} -+ -+static void intc_ftpci100_level_unmask_irq(unsigned int irq) -+{ -+ ftpci_unmask_irq(irq - PLATFORM_PCI_IRQ_BASE); -+} -+ -+static struct irq_chip intc_ftpci100_level_chip = { -+ .ack = intc_ftpci100_level_ack_irq, -+ .mask = intc_ftpci100_level_mask_irq, -+ .unmask = intc_ftpci100_level_unmask_irq, -+}; -+ -+void pci_irq_rounter(unsigned int irq, struct irq_desc *desc) -+{ -+ int pci_irq; -+ struct irq_desc *pci_desc; -+ -+ desc->chip->mask(irq); -+ desc->chip->ack(irq); -+ -+ pci_irq = ftpci_get_irq(); -+ if (pci_irq >= 0) { -+ pci_irq += PCIC_FTPCI100_IRQ0; -+ pci_desc = irq_desc + pci_irq; -+ pci_desc->handle_irq(pci_irq, pci_desc); -+ } -+ -+ desc->chip->unmask(irq); -+} -+ -+int __init intc_ftpci100_init_irq(void) -+{ -+ int i; -+ -+ /* Register all IRQ */ -+ for (i = PCIC_FTPCI100_IRQ0; -+ i < PCIC_FTPCI100_IRQ0 + PCIC_FTPCI100_IRQ_COUNT; i++) { -+ // level trigger -+ set_irq_chip(i, &intc_ftpci100_level_chip); -+ set_irq_handler(i, handle_level_irq); -+ } -+#ifndef CONFIG_PLAT_AG101 -+ set_irq_chained_handler(PLATFORM_PCI_IRQ, pci_irq_rounter); -+#endif -+ -+ return 0; -+} -+ -+subsys_initcall(intc_ftpci100_init_irq); -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/qemu/devices.c linux-3.4.113/arch/nds32/platforms/qemu/devices.c ---- linux-3.4.113.orig/arch/nds32/platforms/qemu/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/qemu/devices.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,124 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+const struct map_desc platform_io_desc[] __initdata = { -+ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, -+ PAGE_SIZE, MT_DEVICE_NCB}, -+ {PCIIO_0_VA_BASE, PCIIO_0_PA_BASE, 0x000FF000, MT_DEVICE_NCB}, -+ {PCIC_FTPCI100_0_VA_BASE, PCIC_FTPCI100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} -+}; -+ -+static void __init platform_map_io(void) -+{ -+ iotable_init((struct map_desc *)platform_io_desc, -+ ARRAY_SIZE(platform_io_desc)); -+} -+ -+static struct uart_port uart0 = { -+ .membase = (void __iomem *)UART0_VA_BASE, -+ .irq = UART0_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 0, -+ .mapbase = UART0_PA_BASE, -+}; -+ -+static struct uart_port uart1 = { -+ .membase = (void __iomem *)UART1_VA_BASE, -+ .irq = UART1_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 1, -+ .mapbase = UART1_PA_BASE, -+}; -+ -+static void __init soc_init(void) -+{ -+ early_serial_setup(&uart0); -+ early_serial_setup(&uart1); -+} -+ -+static struct resource smc91x_resources[] = { -+ [0] = { -+ .name = "smc91x", -+ .start = 0x92100000, -+ .end = 0x92110000, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = 25, -+ .end = 25, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device smc91x_device = { -+ .name = "smc91x", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(smc91x_resources), -+ .resource = smc91x_resources, -+}; -+ -+static __init int smc_init(void) -+{ -+ int ret; -+ ret = platform_device_register(&smc91x_device); -+ if (ret == 0) -+ printk("smc is installed now.\n"); -+ else -+ printk("smc failed.\n"); -+ return 0; -+} -+ -+module_init(smc_init); -+ -+MACHINE_START(FARADAY, PLATFORM_NAME) -+ .param_offset = BOOT_PARAMETER_PA_BASE, -+ .map_io = platform_map_io, -+ .init_irq = platform_init_irq, -+ .timer = &platform_timer, /* defined in timer.c */ -+ .init_machine = soc_init, -+MACHINE_END -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/qemu/Kconfig linux-3.4.113/arch/nds32/platforms/qemu/Kconfig ---- linux-3.4.113.orig/arch/nds32/platforms/qemu/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/qemu/Kconfig 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,3 @@ -+menu "QEMU Platform Options" -+ -+endmenu -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/qemu/Makefile linux-3.4.113/arch/nds32/platforms/qemu/Makefile ---- linux-3.4.113.orig/arch/nds32/platforms/qemu/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/qemu/Makefile 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1 @@ -+obj-y = devices.o -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/timer.c linux-3.4.113/arch/nds32/platforms/timer.c ---- linux-3.4.113.orig/arch/nds32/platforms/timer.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/timer.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,250 @@ -+/* -+ * linux/arch/nds32/platforms/timer.c -+ * -+ * Faraday FTTMR010 Timer Device Driver Implementation -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * Copyright (C) 2009 Andes Technology Corporation -+ * -+ * This program is free software; you can redistribute it and/or modify -+ * it under the terms of the GNU General Public License as published by -+ * the Free Software Foundation; either version 2 of the License, or -+ * (at your option) any later version. -+ * -+ * This program is distributed in the hope that it will be useful, -+ * but WITHOUT ANY WARRANTY; without even the implied warranty of -+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -+ * GNU General Public License for more details. -+ * -+ * You should have received a copy of the GNU General Public License -+ * along with this program; if not, write to the Free Software -+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA -+ * -+ */ -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#define REG32_TMR(x) *(volatile unsigned long *)(TIMER_FTTMR010_VA_BASE + (x)) -+#define APB_CLK_IN (AHB_CLK_IN / 2) -+ -+static struct resource timer_resource = { -+ .name = "Timer 1~3", -+ .start = TIMER_FTTMR010_VA_BASE, -+ .end = TIMER_FTTMR010_VA_LIMIT, -+}; -+ -+static inline cycle_t clocksource_read_cycles(struct clocksource *cs) -+{ -+ return (cycle_t) REG32_TMR(TIMER3_COUNT); -+} -+ -+static void clksrc_fttmr010_resume(struct clocksource *cs) -+{ -+ REG32_TMR(TIMER_INTRMASK) |= TM3MATCH1 | TM3MATCH2 | TM3OVERFLOW; -+ REG32_TMR(TIMER_TMCR) |= TM3UPDOWN | TM3ENABLE; -+} -+ -+static struct clocksource clksrc_fttmr010 = { -+ .name = "fttmr010_tm1", -+ .rating = 300, -+ .read = clocksource_read_cycles, -+ .mask = CLOCKSOURCE_MASK(32), -+ .shift = 21, -+ .flags = CLOCK_SOURCE_IS_CONTINUOUS, -+ .resume = clksrc_fttmr010_resume, -+}; -+ -+static void __init fttmr010_clocksource_init(void) -+{ -+ clksrc_fttmr010.mult = -+ clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift); -+ -+ REG32_TMR(TIMER3_LOAD) = 0; -+ REG32_TMR(TIMER_INTRMASK) |= TM3MATCH1 | TM3MATCH2 | TM3OVERFLOW; -+ REG32_TMR(TIMER_TMCR) |= TM3UPDOWN | TM3ENABLE; -+ if (clocksource_register(&clksrc_fttmr010)) -+ printk(KERN_ERR "Error: failed to register %s\n", -+ clksrc_fttmr010.name); -+} -+ -+static int fttmr010_set_next_event(unsigned long cycles, -+ struct clock_event_device *evt) -+{ -+ REG32_TMR(TIMER1_LOAD) = cycles; -+ return 0; -+} -+ -+static void fttmr010_set_mode(enum clock_event_mode mode, -+ struct clock_event_device *evt) -+{ -+ switch (mode) { -+ case CLOCK_EVT_MODE_ONESHOT: -+ REG32_TMR(TIMER1_LOAD) = 0xffffffff; -+ REG32_TMR(TIMER_TMCR) |= TM1ENABLE; -+ break; -+ -+ case CLOCK_EVT_MODE_PERIODIC: -+ REG32_TMR(TIMER1_COUNT) = APB_CLK_IN / HZ - 1; -+ REG32_TMR(TIMER1_LOAD) = APB_CLK_IN / HZ - 1; -+ REG32_TMR(TIMER_TMCR) |= TM1ENABLE; -+ break; -+ case CLOCK_EVT_MODE_UNUSED: -+ break; -+ case CLOCK_EVT_MODE_SHUTDOWN: -+ REG32_TMR(TIMER_TMCR) &= ~TM1ENABLE; -+ break; -+ case CLOCK_EVT_MODE_RESUME: -+ REG32_TMR(TIMER_INTRMASK) |= TM1MATCH1 | TM1MATCH2; -+ REG32_TMR(TIMER_TMCR) |= TM1ENABLE | TM1OFENABLE; -+ break; -+ } -+} -+ -+static struct clock_event_device clockevent_fttmr010 = { -+ .name = "fttmr010_tm1", -+ .features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_PERIODIC, -+ .shift = 32, -+ .cpumask = cpu_all_mask, -+ .set_next_event = fttmr010_set_next_event, -+ .set_mode = fttmr010_set_mode, -+}; -+ -+static irqreturn_t timer1_interrupt(int irq, void *dev_id) -+{ -+ struct clock_event_device *evt = dev_id; -+ -+ REG32_TMR(TIMER_INTRSTATE) = TM1MATCH1 | TM1MATCH2 | TM1OVERFLOW; -+ -+ evt->event_handler(evt); -+ -+ return IRQ_HANDLED; -+} -+ -+static struct irqaction timer1_irq = { -+ .name = "Timer Tick", -+ .flags = IRQF_DISABLED | IRQF_TIMER | IRQF_IRQPOLL, -+ .handler = timer1_interrupt, -+ .dev_id = &clockevent_fttmr010 -+}; -+ -+static void __init fttmr010_clockevent_init(void) -+{ -+ clockevent_fttmr010.mult = -+ div_sc(APB_CLK_IN, NSEC_PER_SEC, clockevent_fttmr010.shift); -+ clockevent_fttmr010.max_delta_ns = -+ clockevent_delta2ns(0xffffffff, &clockevent_fttmr010); -+ clockevent_fttmr010.min_delta_ns = -+ clockevent_delta2ns(3, &clockevent_fttmr010); -+ -+ clockevents_register_device(&clockevent_fttmr010); -+ setup_irq(TIMER_FTTMR010_IRQ0, &timer1_irq); -+} -+ -+static void fttmr010_resume(void) -+{ -+} -+ -+#ifdef CONFIG_CPU_FREQ -+void ag102_calc_ahb_clk(void); -+static int fttmr010_cpufreq_notifier(struct notifier_block *nb, -+ unsigned long val, void *data) -+{ -+ if (val == CPUFREQ_POSTCHANGE) { -+ -+ unsigned long flags; -+#ifdef CONFIG_PLAT_AG102 -+ ag102_calc_ahb_clk(); -+#endif -+ local_irq_save(flags); -+ -+ clocksource_unregister(&clksrc_fttmr010); -+ -+ clksrc_fttmr010.mult = -+ clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift); -+#ifdef CONFIG_PLAT_AG101 -+ clksrc_fttmr010.mult_orig = -+ clocksource_hz2mult(APB_CLK_IN, clksrc_fttmr010.shift); -+#endif -+ -+ if (clocksource_register(&clksrc_fttmr010)) -+ printk(KERN_ERR "Error: failed to re-register %s\n", -+ clksrc_fttmr010.name); -+ else -+ printk("Re-register clock source %s\n", -+ clksrc_fttmr010.name); -+ -+ local_irq_restore(flags); -+ -+ clockevent_fttmr010.mult = -+ div_sc(APB_CLK_IN, NSEC_PER_SEC, clockevent_fttmr010.shift); -+ -+#ifdef CONFIG_PLAT_AG102 -+ printk("Add timer clock modifier...\n"); -+ fttmr010_set_mode(CLOCK_EVT_MODE_PERIODIC, 0); -+#endif -+ } -+ -+ return 0; -+} -+ -+static struct notifier_block fttmr010_cpufreq_notifier_block = { -+ .notifier_call = fttmr010_cpufreq_notifier -+}; -+ -+static int __init fttmr010_init_cpufreq(void) -+{ -+ if (cpufreq_register_notifier(&fttmr010_cpufreq_notifier_block, -+ CPUFREQ_TRANSITION_NOTIFIER)) -+ printk("fttmr010: Failed to setup cpufreq notifier\n"); -+ -+ return 0; -+} -+ -+core_initcall(fttmr010_init_cpufreq); -+#endif -+ -+static int clksrc_init; -+static void __init fttmr010_init(void) -+{ -+ request_resource(&ioport_resource, &timer_resource); -+ -+ printk -+ ("FTTMR010 timer 1 installed on IRQ %d, with clock %d at %d HZ.\r\n", -+ TIMER_FTTMR010_IRQ0, APB_CLK_IN, HZ); -+ -+ REG32_TMR(TIMER_TMCR) &= -+ ~(TM1ENABLE | TM1CLOCK | TM1OFENABLE | TM1UPDOWN); -+ REG32_TMR(TIMER_INTRMASK) |= TM1MATCH1 | TM1MATCH2; -+ REG32_TMR(TIMER_TMCR) |= TM1OFENABLE; -+ -+ fttmr010_clocksource_init(); -+ fttmr010_clockevent_init(); -+ clksrc_init = 1; -+} -+ -+struct sys_timer platform_timer = { -+ .init = fttmr010_init, -+ .resume = fttmr010_resume, -+}; -+ -+unsigned long long sched_clock(void) -+{ -+ if (clksrc_init) -+ return -+ clocksource_cyc2ns(clocksource_read_cycles -+ (&clksrc_fttmr010), clksrc_fttmr010.mult, -+ clksrc_fttmr010.shift); -+ else -+ return (unsigned long long)(jiffies - INITIAL_JIFFIES) -+ * (NSEC_PER_SEC / HZ); -+} -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/vep/devices.c linux-3.4.113/arch/nds32/platforms/vep/devices.c ---- linux-3.4.113.orig/arch/nds32/platforms/vep/devices.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/vep/devices.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,83 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+const struct map_desc platform_io_desc[] __initdata = { -+ {UART0_VA_BASE, UART0_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {UART1_VA_BASE, UART1_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {INTC_FTINTC010_0_VA_BASE, INTC_FTINTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {TIMER_FTTMR010_0_VA_BASE, TIMER_FTTMR010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SSP_FTSSP010_0_VA_BASE, SSP_FTSSP010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {PMU_FTPMU010_0_VA_BASE, PMU_FTPMU010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {MAC_FTMAC100_0_VA_BASE, MAC_FTMAC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {SDC_FTSDC010_0_VA_BASE, SDC_FTSDC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {RTC_FTRTC010_0_VA_BASE, RTC_FTRTC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {WDT_FTWDT010_0_VA_BASE, WDT_FTWDT010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {GPIO_FTGPIO010_0_VA_BASE, GPIO_FTGPIO010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {CFC_FTCFC010_0_VA_BASE, CFC_FTCFC010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {LCD_FTLCDC100_0_VA_BASE, LCD_FTLCDC100_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {I2C_FTI2C010_0_VA_BASE, I2C_FTI2C010_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {DMAC_FTDMAC020_0_VA_BASE, DMAC_FTDMAC020_0_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {APBBRG_FTAPBBRG020S_0_VA_BASE, APBBRG_FTAPBBRG020S_0_PA_BASE, -+ PAGE_SIZE, MT_DEVICE_NCB}, -+ {LED_VA_BASE, LED_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB}, -+ {SDMC_FTSDMC021_VA_BASE, SDMC_FTSDMC021_PA_BASE, PAGE_SIZE, -+ MT_DEVICE_NCB}, -+ {L2CC_VA_BASE, L2CC_PA_BASE, PAGE_SIZE, MT_DEVICE_NCB} -+}; -+ -+static void __init platform_map_io(void) -+{ -+ iotable_init((struct map_desc *)platform_io_desc, -+ ARRAY_SIZE(platform_io_desc)); -+} -+ -+static struct uart_port uart0 = { -+ .membase = (void __iomem *)UART0_VA_BASE, -+ .irq = UART0_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 0, -+ .mapbase = UART0_PA_BASE, -+}; -+ -+static struct uart_port uart1 = { -+ .membase = (void __iomem *)UART1_VA_BASE, -+ .irq = UART1_IRQ, -+ .uartclk = CONFIG_UART_CLK, -+ .regshift = 2, -+ .iotype = UPIO_MEM, -+ .flags = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF, -+ .line = 1, -+ .mapbase = UART1_PA_BASE, -+}; -+ -+static void __init soc_init(void) -+{ -+ early_serial_setup(&uart0); -+ early_serial_setup(&uart1); -+} -+ -+MACHINE_START(FARADAY, PLATFORM_NAME) -+ .param_offset = BOOT_PARAMETER_PA_BASE,.map_io = platform_map_io,.init_irq = platform_init_irq,.timer = &platform_timer, /* defined in timer.c */ -+ .init_machine = soc_init, MACHINE_END -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/vep/Kconfig linux-3.4.113/arch/nds32/platforms/vep/Kconfig ---- linux-3.4.113.orig/arch/nds32/platforms/vep/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/vep/Kconfig 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,7 @@ -+menu "VEP Platform Options" -+ -+config CACHE_L2 -+ bool "Support L2 cache" -+ default n -+ -+endmenu -diff -Nur linux-3.4.113.orig/arch/nds32/platforms/vep/Makefile linux-3.4.113/arch/nds32/platforms/vep/Makefile ---- linux-3.4.113.orig/arch/nds32/platforms/vep/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/arch/nds32/platforms/vep/Makefile 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1 @@ -+obj-y = devices.o -diff -Nur linux-3.4.113.orig/build_linux.sh linux-3.4.113/build_linux.sh ---- linux-3.4.113.orig/build_linux.sh 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/build_linux.sh 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,202 @@ -+#!/bin/sh -+ -+export ARCH=nds32 -+ -+print_help() -+{ -+ echo "Usage: [platform_defconfig] [--bootm] [--ramdisk=]" -+ echo "Stop Building." -+ exit -+} -+ -+BUILDBOOTM=0 -+BUILDBOOTPIMAGE=0 -+BUILDHEADERS=0 -+ -+case "$1" in -+ qemu) -+ TARGET=qemu_defconfig -+ IMAGE=qemu -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ vep-be) -+ TARGET=vep-be_defconfig -+ IMAGE=vep-be -+ export CROSS_COMPILE=nds32be-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ vep-le) -+ TARGET=vep-le_defconfig -+ IMAGE=vep-le -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ xc5) -+ TARGET=xc5_defconfig -+ IMAGE=xc5 -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ xc5_8k) -+ TARGET=xc5_8k_defconfig -+ IMAGE=xc5_8k -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ ag101a0) -+ TARGET=ag101a0_defconfig -+ IMAGE=ag101a0 -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ ag101b0) -+ TARGET=ag101b0_defconfig -+ IMAGE=ag101b0 -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ ag102) -+ TARGET=ag102_defconfig -+ IMAGE=ag102 -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ u200) -+ TARGET=u200_defconfig -+ IMAGE=u200 -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ xc5-qa) -+ TARGET=xc5-qa_defconfig -+ IMAGE=xc5-qa -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ ag101-qa) -+ TARGET=ag101-qa_defconfig -+ IMAGE=ag101-qa -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+ ;; -+ *) -+ if [ $# = 1 ]; then -+ echo "No defconfig is given." -+ print_help -+ fi -+ if [ ! -e $2 ]; then -+ echo "Given defconfig is not exist." -+ print_help -+ elif [ ! -f $2 ]; then -+ echo "Given defconfig is not a file." -+ print_help -+ elif [ ! -s $2 ]; then -+ echo "Given defconfig is size 0." -+ print_help -+ elif [ ! -r $2 ]; then -+ echo "Given defconfig has no read attribute." -+ print_help -+ fi -+ TARGET=none -+ IMAGE=$1 -+ export CROSS_COMPILE=nds32le-linux- -+ echo "Building $IMAGE kernel." -+esac -+ -+ZIMAGE="$IMAGE"_zImage -+VMLINUZ="$IMAGE"_vmlinuz -+VMLINUX="$IMAGE"_vmlinux -+BOOTPIMAGE="$IMAGE"_bootpImage -+BOOTP="$IMAGE"_bootp -+BOOTM="$IMAGE"_bootm -+ -+for ARG in $@; do -+ if [ $ARG = $1 ]; then -+ continue -+ fi -+ -+ if [ $ARG = $2 ]; then -+ if [ $TARGET = "none" ]; then -+ continue -+ fi -+ fi -+ -+ case "$ARG" in -+ -+ --bootm) -+ BUILDBOOTM=1 -+ ;; -+ -+ --ramdisk=*) -+ BUILDBOOTPIMAGE=1 -+ RAMDISK=${ARG#*=} -+ if [ ! -e $RAMDISK ]; then -+ echo "Given ramdisk is not exist." -+ print_help -+ elif [ ! -f $RAMDISK ]; then -+ echo "Given ramdisk is not a file." -+ print_help -+ elif [ ! -s $RAMDISK ]; then -+ echo "Given ramdisk is size 0." -+ print_help -+ elif [ ! -r $RAMDISK ]; then -+ echo "Given ramdisk has no read attribute." -+ print_help -+ fi -+ ;; -+# --headers) -+# BUILDHEADERS=1 -+# git apply ../linux-2.6-patch/headers.patch -+# echo "Exporting kernel headers." -+# ;; -+ *) -+ print_help -+ esac -+done -+ -+if [ "$OSTYPE" = "cygwin" ]; then -+ HOST_LOADLIBES=-lintl\ -lcurses -+fi -+export HOST_LOADLIBES -+ -+which ${CROSS_COMPILE}gcc &> /dev/null || export CROSS_COMPILE=nds32-elf- -+ -+make mrproper | tee $IMAGE.log -+if [ $TARGET != "none" ]; then -+ make $TARGET| tee -a $IMAGE.log -+else -+ cp $2 .config -+fi -+ -+if [ $BUILDHEADERS = 1 ]; then -+ make dep | tee -a $IMAGE.log -+ make headers_install | tee -a $IMAGE.log -+else -+ make | tee -a $IMAGE.log -+ -+ cp arch/nds32/boot/zImage ./$ZIMAGE | tee -a $IMAGE.log -+ cp arch/nds32/boot/compressed/vmlinux ./$VMLINUZ | tee -a $IMAGE.log -+ cp ./vmlinux ./$VMLINUX | tee -a $IMAGE.log -+ -+ if [ $BUILDBOOTPIMAGE = 1 ]; then -+ make bootpImage INITRD=$RAMDISK | tee -a $IMAGE.log -+ cp arch/nds32/boot/bootpImage ./$BOOTPIMAGE | tee -a $IMAGE.log -+ cp arch/nds32/boot/bootp/bootp ./$BOOTP | tee -a $IMAGE.log -+ fi -+ -+ if [ $BUILDBOOTM = 1 ]; then -+ if [ -e "../u-boot/tools/mkimage" ]; then -+ ../u-boot/tools/mkimage \ -+ -A nds32 \ -+ -O linux \ -+ -T kernel \ -+ -C none \ -+ -a 0x500000 \ -+ -e 0x500040 \ -+ -d ./arch/nds32/boot/zImage $BOOTM | tee -a $IMAGE.log -+ else -+ echo "Error: ../u-boot/tools/mkimage not found" | tee -a $IMAGE.log -+ fi -+ fi -+fi -diff -Nur linux-3.4.113.orig/drivers/block/ftcfc010.c linux-3.4.113/drivers/block/ftcfc010.c ---- linux-3.4.113.orig/drivers/block/ftcfc010.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/block/ftcfc010.c 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,1299 @@ -+/* drivers/block/CPESD/ftsdc010.c -+ ******************************************************************************* -+ * Faraday FTSDC010 Device Driver -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * All Rights Reserved -+ * -+ * Porting to Linux 2.6 on 20050815 -+ * Author: Chris Lee, I-Jui Sung, Peter Liao (support APB DMA) -+ * Version: 0.2 -+ * History: -+ * 0.1 new creation -+ * 0.2 Porting to meet the style of linux dma -+ * 0.3 modify dma usage to virtual irq of dma interrupt -+ * 0.4 (20050701) Improve r/w performance -+ * 0.5 Porting to Linux 2.6 and replace busy_loop checking with timer's timeout -+ * Todo: -+ ******************************************************************************* -+ */ -+ -+#define DEBUG_OFF 0 -+ -+#define DEBUG( enable, tagged, ...) \ -+do{ \ -+ if( enable){ \ -+ if( tagged) \ -+ printk( "[ %30s() ] ", __func__); \ -+ printk( __VA_ARGS__); \ -+ } \ -+} while( 0) -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* HDIO_GETGEO */ -+#include -+#include -+#include /* invalidate_bdev */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define IPMODULE CFC -+#define IPNAME FTCFC010 -+ -+#include "ftcfc010.h" -+ -+static int hardsect_size = 512; -+module_param( hardsect_size, int, 0); -+ -+static int cf_major = 0; /* must be declared before including blk.h */ -+#define DEVICE_NAME "Faraday CFC" /* name for messaging */ -+ -+#define FTCFC_VA_BASE IP_VA_BASE( 0) -+#define FTCFC_PA_BASE IP_PA_BASE( 0) -+#define FTCFC_IRQ CFC_FTCFC010_IRQ1 -+ -+#undef CF_DEBUG -+#define CF_DEBUG 0 -+struct block_device_operations cf_fops; -+ -+typedef struct cf_dev { -+ -+ int size; /* device size in sectors */ -+ int usage; /* # of users currently */ -+ int media_change; /* Flag: media changed? */ -+ struct gendisk *gd; /* The gendisk structure */ -+ spinlock_t lock; /* For mutual exclusion */ -+ struct request_queue *queue; /* The device request queue */ -+ int card_state; -+ u32 lba_sec_offset; -+ dmad_chreq ch_req; -+ -+} cf_dev_t; -+ -+static cf_dev_t *cf_devices; -+static cf_card_t cf_card_info; -+ -+static dma_addr_t dma_buf; -+struct completion cf_dma_cmpl; -+ -+static uint first_run; -+static uint cf_err_code; -+ -+static int g_cf_sectors; -+ -+static void SetTransferSize( u32 Addr, u32 Type, u32 OP_Type, u32 Inc_Addr, u32 Transize) -+{ -+ u32 ctrl_reg, buf_ctrl_reg; -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ /* set read/write command */ -+ while( cfc->HostStatus & BUF_ACTIVE_BIT) -+ ; -+ -+ /* Set Transfer size mode to default */ -+ cfc->TransSzMode2En = 0; -+ -+ /* set 8/16 bits mode */ -+ ctrl_reg = cfc->ControlReg; -+ -+ if( Transize == SIZE_1_BYTE) -+ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | BYTE_MODE; -+ else -+ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | WORD_MODE; -+ -+ DEBUG( CF_DEBUG, 1, "ctrl 1: 0x%08lx\n", ( unsigned long)ctrl_reg); -+ cfc->ControlReg = ctrl_reg; -+ -+ /* Write command to buffer */ -+ buf_ctrl_reg = cfc->BuffCtrlReg; -+ buf_ctrl_reg = ( buf_ctrl_reg & ~ADR_BIT & ~TYPE_BIT & ~RW_BIT & ~INCADR_BIT & ~TRANS_SIZE_CONTROL_BIT) -+ | Addr | Type | OP_Type | Inc_Addr | ( Transize << TRANS_SIZE_LOC); -+ -+ cfc->BuffCtrlReg = buf_ctrl_reg; -+ DEBUG( CF_DEBUG, 1, "buf_ctrl 1: 0x%08lx\n", ( unsigned long)buf_ctrl_reg); -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+} -+ -+static void SetTransferSizeEx( u32 Addr, u32 Type, u32 OP_Type, u32 Inc_Addr, u32 Transize) -+{ -+ u32 ctrl_reg, buf_ctrl_reg; -+ -+ DEBUG( CF_DEBUG, 1, "Enter, SetTransferSizeEx: %d\n", Transize); -+ -+ /* set read/write command */ -+ while( cfc->HostStatus & BUF_ACTIVE_BIT) -+ ; -+ -+ /* Set Transfer size mode to default */ -+ cfc->TransSzMode2En = 1; -+ -+ /* set 8/16 bits mode */ -+ ctrl_reg = cfc->ControlReg; -+ -+ if( Transize == SIZE_1_BYTE) -+ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | BYTE_MODE; -+ else -+ ctrl_reg = ( ctrl_reg & ~MODE_BIT) | WORD_MODE; -+ -+ cfc->ControlReg = ctrl_reg; -+ -+ /* Set Transfer size mode2 reg in FTCFC */ -+ cfc->TransSzMode2Cnt = Transize - 1; -+ -+ /* Write command to buffer */ -+ buf_ctrl_reg = cfc->BuffCtrlReg; -+ buf_ctrl_reg = ( buf_ctrl_reg & ~ADR_BIT & ~TYPE_BIT & ~RW_BIT & ~INCADR_BIT & ~TRANS_SIZE_CONTROL_BIT) -+ | Addr | Type | OP_Type | Inc_Addr; -+ -+ cfc->BuffCtrlReg = buf_ctrl_reg; -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+} -+ -+static void WriteCFCardByte( u32 Addr, u8 Value, u32 Type) -+{ -+ while( !( cfc->HostStatus & RDY_nIREQ_BIT)) -+ ; -+ -+ SetTransferSize( Addr, Type, WRITE_OP, NOINCADR, SIZE_1_BYTE); -+ -+ cfc->BufferData = Value; -+ -+ while( !( cfc->HostStatus & INTA_BIT)) -+ ; -+ -+ /* clear command complete status */ -+ cfc->HostStatus = INTA_BIT; -+} -+ -+static u8 ReadCFCardByte( u32 Addr, u32 Type) -+{ -+ u8 ret_data; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ /* wait until ready */ -+ while( !( cfc->HostStatus & RDY_nIREQ_BIT)) -+ ; -+ -+ SetTransferSize( Addr, Type, READ_OP, NOINCADR, SIZE_1_BYTE); -+ -+ while( !( cfc->HostStatus & INTA_BIT)) -+ ; -+ -+ ret_data = cfc->BufferData & 0xff; -+ DEBUG( CF_DEBUG, 1, "data: 0x%02x\n", ret_data); -+ -+ while( !( cfc->HostStatus & INTA_BIT)) -+ ; -+ -+ /* clear command complete status */ -+ cfc->HostStatus = INTA_BIT; -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ return ret_data; -+} -+ -+/* set Head-cylinder-sector on CF */ -+static u32 Translate_Config_HCS( u32 LBA, u32 Sec_count) -+{ -+ u8 DriveHead = ( u8)( 0xE0 | ( LBA >> 24)); /* 0xE0 set in LBA mode (bit 7&5 must set to 1) */ -+ u8 CylHigh = ( u8)( ( LBA >> 16) & 0xFF); -+ u8 CylLow = ( u8)( ( LBA >> 8) & 0xFF); -+ u8 SecNum = ( u8)( LBA & 0xFF); -+ -+ DEBUG( CF_DEBUG, 1, "LBA:%d, %d %d %d %d, count: %d\n", -+ LBA, DriveHead, CylHigh, CylLow, SecNum, Sec_count); -+ -+ /* Set CF-ATA reg for start sector */ -+ WriteCFCardByte( BLKMEM_DRIVE_REG, DriveHead, COMMON_MEM); -+ WriteCFCardByte( BLKMEM_CYLINDER_HIGH_REG, CylHigh, COMMON_MEM); -+ WriteCFCardByte( BLKMEM_CYLINDER_LOW_REG, CylLow, COMMON_MEM); -+ WriteCFCardByte( BLKMEM_SECTOR_NUMBER_REG, SecNum, COMMON_MEM); -+ WriteCFCardByte( BLKMEM_SECTOR_COUNT_REG, Sec_count, COMMON_MEM); -+ -+ return 1; -+} -+ -+/* -+ * SetCFCardConfiguration(): ATTRIBUTE MEMORY -+ * Set CF storgae card configuration option register -+ * Conf1 Conf0 Disk Card Mode -+ * --------------------------------------------------------------- -+ * 0 0 Memory Mapped -+ * 0 1 I/O Mapped, any 16 byte system decoded -+ * 1 0 I/O Mapped, 1F0h - 1F7h / 3F6h - 3F7h -+ * 1 1 I/O Mapped, 170h - 177h / 376h - 377h -+ */ -+static void SetCFCardMode( u8 Mode) -+{ -+ u8 Reg; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ Reg = ReadCFCardByte( CONFIG_OPTION_REG, ATTRIBUTE_MEM); /* CONFIG_OPTION_REG = 0x200 */ -+ Reg &= ( LEVLREQ_BIT | SRESET_BIT); /* clear bit0-5 */ -+ -+ WriteCFCardByte( CONFIG_OPTION_REG, Reg | Mode, ATTRIBUTE_MEM); -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+} -+ -+/* return 0: fail, 1: success */ -+static u32 CF_SendCommand( u16 Cmd) -+{ -+ u16 Reg; -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ do{ -+ WriteCFCardByte( BLKMEM_COMMAND_REG, Cmd, COMMON_MEM); -+ -+ /* -+ * Check status register of Task file register is valid for access -+ * No other bits in status register are valid when BUSY bit is -+ * set to a 1 -+ */ -+ while( ( ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM) & BUSY_BIT)) -+ ; -+ -+ Reg = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ if( Reg & ERR_BIT){ -+ -+ DEBUG( CF_DEBUG, 1, "Exit ( fail)\n"); -+ return 0; -+ } -+ -+ } while( !( Reg & RDY_BIT)); -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ return 1; -+} -+ -+static void CardReset( void) -+{ -+ u32 ctrl_reg = cfc->ControlReg; -+ u8 data; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ cfc->ControlReg = ctrl_reg | RESET_BIT | SIGNAL_ON | PWR_ON; /* set reset bit, float control, power on */ -+ -+ /* Software must manually clear this bit */ -+ mdelay( 100); -+ -+ /* clear reset bit */ -+ cfc->ControlReg = ( ctrl_reg &~ RESET_BIT) | SIGNAL_ON | PWR_ON | DATA_CMP_INT_MASK | IO_INT_MASK; -+ -+ do { -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ } while( data & BUSY_BIT); /* please be careful that is locked here */ -+ -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ /* Check if Drive Ready & Drive Seek Complete */ -+ if( data == ( RDY_BIT | DSC_BIT)) -+ DEBUG( CF_DEBUG, 1, "Reset CF OK, data: 0x%02x\n", ( unsigned char)data); -+ else -+ DEBUG( CF_DEBUG, 1, "Reset CF fail, data: 0x%02x\n", ( unsigned char)data); -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+} -+ -+static u32 CFCardInit( void) -+{ -+ u8 buff[CF_SECTOR_SIZE]; -+ u32 i; -+ u32 BSA, BSM, BSIO, BSMOW, BSIORW, apb_ns; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ if( !( cfc->HostStatus & CARD_DETECT_BIT)){ -+ -+ DEBUG( CF_DEBUG, 1, "No CF Card In Socket\n"); -+ return -1; -+ } -+ -+ CardReset(); -+ -+ /* set timer */ -+ -+ apb_ns = 1000000000 / ( AHB_CLK_IN / 2 ); /* the time of APB clock */ -+ BSA = ( 50 + ( apb_ns - ( 50 % apb_ns))) / apb_ns; /* Based on the item tc( R) of BSA */ -+ BSMOW = 3; -+ BSIORW = 3; -+ BSM = ( 30 + ( apb_ns - ( 30 % apb_ns))) / apb_ns; /* Base on the item tw( WE) of BSM */ -+ BSIO = ( 35 + ( apb_ns - ( 35 % apb_ns))) / apb_ns; /* Base on the item tsuA( IORD,IOWR) of BSIO */ -+ -+ cfc->TimeCfgReg = ( ( BSMOW & 0x03) << 12) -+ | ( ( BSIORW & 0x03) << 14) -+ | ( ( BSA & 0x0f) << 0) -+ | ( ( BSM & 0x0f) << 4) -+ | ( ( BSIO & 0x0f) << 8); -+ -+ SetCFCardMode( CF_MEM_MAP_MODE); /* set memory mode read write access */ -+ -+ cfc->MultiSector = 0x1; /* enable multi sector read/write */ -+ -+ /* select drive */ -+ WriteCFCardByte( BLKMEM_DRIVE_REG, 0, COMMON_MEM); -+ -+ /* identify drive device */ -+ if( !CF_SendCommand( ATA_IDENTIFY_DRIVE)){ -+ -+ DEBUG( CF_DEBUG, 1, "Send Identify Drive command fail\n"); -+ return -1; -+ } -+ -+ SetTransferSize( BLKMEM_DATA_REG, COMMON_MEM, READ_OP, NOINCADR, SIZE_512_BYTE); -+ -+ for( i = 0; i < CF_SECTOR_SIZE / 4; i++){ -+ -+ while( !( cfc->HostStatus & BUF_DATA_RDY_BIT)) -+ ; -+ -+ *( ( u32*)&buff[ i*4]) = cfc->BufferData; -+ } -+ -+ /* clear command complete status */ -+ cfc->HostStatus = INTA_BIT; -+ -+ g_cf_sectors = ( ( u32)buff[ 15] << 24) | ( ( u32)buff[ 14] << 16) | ( ( u32)buff[ 17] << 8) | ( ( u32)buff[ 16]); -+ DEBUG( CF_DEBUG, 1, "Card identify - capicity: %d sectors, size: %d kbytes \n", g_cf_sectors, g_cf_sectors >> 1); -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ -+ return 0; -+} -+ -+static int cfc_read_block( cf_card_t *info, uint size, uint *buf) -+{ -+ /* -+ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 ( page 5-76) to set the timeout setting -+ */ -+ unsigned long timeout = jiffies + CFC_TIMEOUT_BASE *( ( size + 2048 + 511) >> 9); -+ uint count; -+ u8 data; -+ dmad_chreq *ch_req = (dmad_chreq *)info->private; -+ dmad_drb *drb = 0; -+ u32 drb_size = 0; -+ dma_addr_t addr_iter; -+ -+ if( info->DMAEnable){ -+ -+ DEBUG( CF_DEBUG, 1, "DMA Read - size: %d, buf: 0x%08lx, dma_buf: 0x%08lx\n", -+ size, ( unsigned long)buf, ( unsigned long)dma_buf); -+ -+ init_completion(&cf_dma_cmpl); -+ -+ if (dma_buf) -+ consistent_sync(__va(dma_buf), size, DMA_FROM_DEVICE); -+ else -+ consistent_sync(buf, size, DMA_FROM_DEVICE); -+ -+ //prepare parameter for add dma entry -+ dmad_config_channel_dir(ch_req, DMAD_DIR_A0_TO_A1); -+ -+ drb_size = dmad_max_size_per_drb(ch_req); -+ -+ if (dma_buf) -+ addr_iter = dma_buf; // given dest phy addr -+ else -+ addr_iter = __pa(buf); -+ -+ cfc->ControlReg |= ENDMA_BIT; -+ -+ while (size > 0) { -+ -+ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { -+ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); -+ return FALSE; -+ } -+ -+ drb->addr0 = FTCFC_PA_BASE + 0x10; -+ drb->addr1 = addr_iter; -+ -+ if (size <= drb_size) { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); -+ drb->sync = &cf_dma_cmpl; -+ size = 0; -+ } else { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); -+ drb->sync = 0; -+ size -= drb_size; -+ addr_iter += drb_size; -+ } -+ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); -+ -+ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { -+ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); -+ return FALSE; -+ } -+ } -+ -+ if (wait_for_completion_timeout(&cf_dma_cmpl, timeout - jiffies) == 0) -+ printk("%s: read timeout\n", __func__); -+ -+ DEBUG( CF_DEBUG, 1, "ControlReg: 0x%08x, HostStatus: 0x%08x, BufCtrl: 0x%08x\n", -+ cfc->ControlReg, cfc->HostStatus, cfc->BuffCtrlReg); -+ -+ while( !( cfc->HostStatus & INTA_BIT)) -+ ; -+ -+ cfc->HostStatus = INTA_BIT; -+ -+ /* Stop DMA */ -+ cfc->ControlReg &= ~ENDMA_BIT; -+ cfc->ControlReg &= ~MODE_BIT; -+ -+ do { -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ } while( data & BUSY_BIT); -+ } -+ else { -+ while( size > 0){ -+ -+ /* read data from FIFO */ -+ if( size >= ( CFC_READ_FIFO_LEN << 2)) -+ count = CFC_READ_FIFO_LEN; -+ else -+ count = size >> 2; -+ -+ /* read data from FIFO */ -+ DEBUG( CF_DEBUG, 0, "\n"); -+ size -= ( count << 2); -+ } -+ } -+ -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ while( 1){ -+ -+ if( data & ERR_BIT){ -+ -+ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF Read sector error.\n"); -+ return FALSE; -+ } -+ else if( data & DWF_BIT){ -+ -+ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF write fault error.\n"); -+ return FALSE; -+ } -+ else if( data & ( RDY_BIT | DSC_BIT)){ -+ -+ break; -+ } -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ } -+ -+ return TRUE; -+} -+ -+static int cfc_write_block( cf_card_t *info, uint size, uint *buf) -+{ -+ unsigned long timeout = jiffies + CFC_TIMEOUT_BASE * 3 *( ( size + 511) >> 9); -+ uint count; -+ u8 data; -+ dmad_chreq *ch_req = (dmad_chreq *)info->private; -+ dmad_drb *drb = 0; -+ u32 drb_size = 0; -+ dma_addr_t addr_iter; -+ -+ if( info->DMAEnable){ -+ -+ DEBUG( CF_DEBUG, 1, "size: %d, buf: %p) - DMA Write\n", size, buf); -+ -+ init_completion(&cf_dma_cmpl); -+ -+ if (dma_buf) -+ consistent_sync(__va(dma_buf), size, DMA_TO_DEVICE); -+ else -+ consistent_sync(buf, size, DMA_TO_DEVICE); -+ -+ //prepare parameter for add dma entry -+ dmad_config_channel_dir(ch_req, DMAD_DIR_A1_TO_A0); -+ -+ drb_size = dmad_max_size_per_drb(ch_req); -+ -+ if (dma_buf) -+ addr_iter = dma_buf; // given dest phy addr -+ else -+ addr_iter = __pa(buf); -+ -+ cfc->ControlReg |= ENDMA_BIT; -+ -+ while (size > 0) { -+ -+ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { -+ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); -+ return FALSE; -+ } -+ -+ drb->addr0 = FTCFC_PA_BASE + 0x10; -+ drb->addr1 = addr_iter; -+ -+ if (size <= drb_size) { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); -+ drb->sync = &cf_dma_cmpl; -+ size = 0; -+ } else { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); -+ drb->sync = 0; -+ size -= drb_size; -+ addr_iter += drb_size; -+ } -+ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); -+ -+ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { -+ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); -+ return FALSE; -+ } -+ } -+ -+ if (wait_for_completion_timeout(&cf_dma_cmpl, timeout - jiffies) == 0) -+ printk("write timeout\n"); -+ -+ while( !( cfc->HostStatus & INTA_BIT)) -+ ; -+ -+ cfc->HostStatus = INTA_BIT; -+ /* Stop DMA */ -+ cfc->ControlReg &= ~ENDMA_BIT; -+ cfc->ControlReg &= ~MODE_BIT; -+ -+ do{ -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ } while( data & BUSY_BIT); -+ } -+ else { -+ while( size > 0){ -+ -+ /* write data from FIFO */ -+ if( size >= ( CFC_WRITE_FIFO_LEN << 2)) -+ count = CFC_WRITE_FIFO_LEN; -+ else -+ count = ( size >> 2); -+ -+ size -= ( count << 2); -+ } -+ } -+ -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ while( 1){ -+ -+ if( data & ERR_BIT){ -+ -+ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF Read sector error.\n"); -+ return FALSE; -+ } -+ else if( data & DWF_BIT){ -+ -+ DEBUG( CF_DEBUG, 1, "ERROR: ( CFReadSector) CF write fault error.\n"); -+ return FALSE; -+ } -+ else if( data & ( RDY_BIT | DSC_BIT)) -+ break; -+ -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ } -+ return TRUE; -+} -+ -+static int cf_card_insert( cf_card_t *info) -+{ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ CardReset(); -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ -+ return TRUE; -+} -+ -+/* Free IRQ and DMA resources */ -+static void cf_free( cf_dev_t *dev) -+{ -+ release_region( FTCFC_VA_BASE, 0x48); /* return ioport */ -+ free_irq( FTCFC_IRQ, dev); /* return Hotswapping irq */ -+ -+ if (cf_card_info.DMAEnable) { -+#if (CF_DEBUG) -+ if (dev->ch_req.controller == DMAD_DMAC_APB_CORE) -+ printk("%s: free APB dma channel (%d)\n", __func__, dev->ch_req.channel); -+ else -+ printk("%s: free AHB dma channel (%d)\n", __func__, dev->ch_req.channel); -+#endif -+ dmad_channel_free(&dev->ch_req); -+ cf_card_info.DMAEnable = FALSE; -+ } -+} -+ -+static int cf_card_remove( cf_card_t *info) -+{ -+ cf_err_code = ERR_NO_ERROR; -+ -+ info->ActiveState = FALSE; -+ info->WriteProtect = FALSE; -+ info->RCA = 0; -+ -+ /* reset host interface controller */ -+ cfc->ControlReg |= RESET_BIT; -+ -+ mdelay( 100); -+ cfc->ControlReg &= ~RESET_BIT; /* must manually clear reset bit */ -+ return TRUE; -+} -+ -+irqreturn_t cf_hotswap_interrupt_handler( int irq, void *dev_id) -+{ -+ cf_dev_t *dev = dev_id; -+ -+ DEBUG( CF_DEBUG, 1, "irq: %d\n", irq); -+ -+ /* -+ * When the card is inserted or removed, we must delay a short time to make sure -+ * the SDC_STATUS_REG_CARD_INSERT bit of status register is stable -+ */ -+ -+ if( cfc->HostStatus & INT_CD_BIT ){ -+ -+ mdelay( 100); /* wait 0.1 sec for card stable */ -+ -+ DEBUG( CF_DEBUG, 1, "Card %s\n", cfc->HostStatus & CARD_DETECT_BIT ? "Insert" : "Remove"); -+ if( cfc->HostStatus & CARD_DETECT_BIT ){ -+ -+ dev->card_state = CF_CARD_INSERT; -+ cf_card_insert( &cf_card_info); -+ } -+ else { -+ dev->card_state = CF_CARD_REMOVE; -+ cf_card_remove( &cf_card_info); -+ } -+ -+ cfc->HostStatus = INT_CD_BIT; -+ } -+ else{ -+ DEBUG( CF_DEBUG, 1, "cfc->HostStatus & INT_CD_BIT == 0\n"); -+ } -+ -+ DEBUG( CF_DEBUG, 1, "Exit: card state = %d\n", dev->card_state); -+ return IRQ_HANDLED; -+} -+ -+int cf_read_multiple_block( cf_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) -+{ -+ u8 data; -+ -+ DEBUG( CF_DEBUG, 1, "read block addr: 0x%x(%d) sectors: %d\n", addr, addr, count); -+ -+ cf_err_code = ERR_NO_ERROR; -+ Translate_Config_HCS( addr, count); -+ CF_SendCommand( ATA_READ_SECTOR); -+ -+ do{ -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ -+ } while( data & BUSY_BIT); -+ -+ SetTransferSizeEx( BLKMEM_DATA_REG, COMMON_MEM, READ_OP, NOINCADR, CF_SECTOR_SIZE * count); -+ -+ if( first_run == 0){ -+ -+ udelay( 100000); -+ -+ first_run = 1; -+ } -+ -+ if( !cfc_read_block( info, CF_SECTOR_SIZE * count, ( uint *)buf)) -+ return FALSE; -+ -+ if( cf_err_code != ERR_NO_ERROR){ -+ -+ DEBUG( CF_DEBUG, 1, "error = 0x%x\n", cf_err_code); -+ DEBUG( CF_DEBUG, 1, "r addr %d count %d\n", addr, count); -+ -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+int cf_write_multiple_block( cf_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) -+{ -+ u8 data; -+ -+ DEBUG( CF_DEBUG, 1, "write block addr: 0x%08lx, sectors: %x, sector: %x\n", ( unsigned long)addr, count, 512); -+ -+ cf_err_code = ERR_NO_ERROR; -+ Translate_Config_HCS( addr, count); -+ CF_SendCommand( ATA_WRITE_SECTOR); -+ do { -+ data = ReadCFCardByte( BLKMEM_STATUS_REG, COMMON_MEM); -+ } while( data & BUSY_BIT); -+ -+ SetTransferSizeEx( BLKMEM_DATA_REG, COMMON_MEM, WRITE_OP, NOINCADR, CF_SECTOR_SIZE * count); -+ -+ if( !cfc_write_block( info, CF_SECTOR_SIZE*count, ( uint *) buf)) -+ return FALSE; -+ -+ if( cf_err_code != ERR_NO_ERROR){ -+ -+ DEBUG( CF_DEBUG, 1, "error: 0x%08lx\n", ( unsigned long)cf_err_code); -+ DEBUG( CF_DEBUG, 1, "w addr: %d, count: %d\n", addr, count); -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+ -+/*************************************************************************** -+ * SD Card Read/Write/Erase Function -+ ***************************************************************************/ -+int cf_read_sector( cf_card_t *info, uint addr, uint count, unchar *buf) -+{ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ if( !cf_read_multiple_block( info, addr + cf_devices->lba_sec_offset, count, -+ info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)){ -+ -+ DEBUG( CF_DEBUG, 1, "read failed\n"); -+ return FALSE; -+ } -+ -+ DEBUG( CF_DEBUG, 1, "read ok\n"); -+ -+ if( cf_devices->lba_sec_offset == 0){ -+ -+ if( !cf_read_multiple_block( info, 0, 1, info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)) -+ return FALSE; -+ -+ /* lba ( ??) sector offset */ -+ cf_devices->lba_sec_offset = ( *( buf + 0x1C6)) -+ | ( *( buf + 0x1C7)) << 8 -+ | ( *( buf + 0x1C8)) << 16 -+ | ( *( buf + 0x1C9)) << 24; -+ -+ /* device total sector number */ -+ g_cf_sectors = ( *( buf + 0x1CA)) -+ | ( *( buf + 0x1CB)) << 8 -+ | ( *( buf + 0x1CC)) << 16 -+ | ( *( buf + 0x1CD)) << 24; -+ -+ /* only for testing , it only to let format command ok */ -+ if( ( buf[ 0x1be] != 0x0) && ( buf[ 0x1be] != 0x80)) /* partition identify */ -+ cf_devices->lba_sec_offset = 0; /* sector 0 is PBR */ -+ else -+ cf_devices->lba_sec_offset = ( buf[ 0x1c6]) -+ | ( buf[ 0x1c7] << 8) -+ | ( buf[ 0x1c8] << 16) -+ | ( buf[ 0x1c9] << 24); -+ -+ DEBUG( CF_DEBUG, 1, "lba_sec_offet is %d\n", cf_devices->lba_sec_offset); -+ DEBUG( CF_DEBUG, 1, "the device( partition) total sector number is %d\n", g_cf_sectors); -+ } -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ return TRUE; -+} -+ -+int cf_write_sector( cf_card_t *info, uint addr, uint count, unchar *buf) -+{ -+ if( !cf_write_multiple_block( info, addr+cf_devices->lba_sec_offset, count, -+ info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)){ -+ -+ DEBUG( CF_DEBUG, 1, "write failed\n"); -+ -+ return FALSE; -+ } -+ -+ DEBUG( CF_DEBUG, 1, "write ok\n"); -+ -+ return TRUE; -+} -+ -+/* -+ * Perform an actual transfer: -+ * Returns: # of sectors transferred. 0 = error -+ */ -+int cf_transfer( cf_dev_t *device, const struct request *req) -+{ -+ int status = 0; -+ int count = 0; -+ -+ struct bio *bio = req->bio; -+ struct bio_vec *bvec; -+ struct req_iterator iter; -+ -+ DEBUG( CF_DEBUG, 1, "req sector: %d, phys_seg: %d, buf: 0x%08lx\n", -+ (int)req->__sector, req->nr_phys_segments, -+ (unsigned long)bio_data(bio)); -+ -+ spin_unlock_irq( &device->lock); -+ -+ rq_for_each_segment( bvec, req, iter){ -+ -+ unsigned char *buf = page_address( bvec->bv_page) + bvec->bv_offset; -+ int sectors = bio_cur_bytes( bio) >> 9; -+ -+ DEBUG( CF_DEBUG, 1, "bvec[%2d]: sector: %d, count: %d, curr: %d, buf: 0x%08lx\n", -+ iter.i, ( int)bio->bi_sector, count, ( int)sectors, ( unsigned long)buf); -+ -+ cf_card_info.private = (void *)&device->ch_req; -+ -+ if( rq_data_dir( req) == 0) /* Read */ -+ status = cf_read_sector( &cf_card_info, bio->bi_sector, sectors, buf); -+ else -+ status = cf_write_sector( &cf_card_info, bio->bi_sector, sectors, buf); -+ -+ DEBUG( CF_DEBUG, 1, "status: %d\n", status); -+ -+ if (status <= 0) { -+ spin_lock_irq( &device->lock); -+ return count; -+ } -+ -+ count += sectors; -+ bio->bi_sector += sectors; -+ } -+ -+ spin_lock_irq( &device->lock); -+ -+ if( status <= 0) -+ return 0; -+ else -+ return count; -+} -+ -+static int cf_card_setup(cf_dev_t *dev) -+{ -+ int i; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ first_run = 0; -+ cf_err_code = ERR_NO_ERROR; -+ -+ cf_card_info.ActiveState = FALSE; -+ cf_card_info.WriteProtect = FALSE; -+ cf_card_info.IOAddr = FTCFC_VA_BASE; -+ cf_card_info.DMAEnable = TRUE; -+ cf_card_info.DMAChannel = dev->ch_req.channel; -+ cf_card_info.SysFrequency = AHB_CLK_IN / 2; -+ cf_card_info.RCA = 0; -+ -+ DEBUG( CF_DEBUG, 1, "DMA Enable is %d, Sys frequency = %d\n", cf_card_info.DMAEnable, cf_card_info.SysFrequency); -+ -+ if( !cf_card_insert( &cf_card_info)) -+ return FALSE; -+ -+ /* Marketing MB is not 1048576 */ -+ DEBUG( CF_DEBUG, 1, "FTCFC010: CF Card Capacity = %d KBytes\n", g_cf_sectors >> 1); -+ -+ for( i = 0; i < CF_DEVS; i++) -+ cf_devices[i].size = g_cf_sectors; /* unit is block, not bytes */ -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ -+ return TRUE; -+} -+ -+int cf_ioctl( struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) -+{ -+ int size; -+ struct hd_geometry geo; -+ cf_dev_t *device = bdev->bd_disk->private_data; -+ -+ DEBUG( CF_DEBUG, 1, "ioctl 0x%x 0x%lx\n", cmd, arg); -+ -+ switch ( cmd){ -+ -+ case BLKGETSIZE: -+ /* -+ * Return the device size, expressed in sectors -+ * FIXME: distinguish between kernel sector size and media sector size -+ */ -+ size = device->size; -+ __copy_to_user ( ( long *) arg, &size, sizeof ( long)); -+ return 0; -+ -+ case HDIO_GETGEO: -+ /* -+ * get geometry: we have to fake one... trim the size to a -+ * multiple of 64 ( 32k): tell we have 16 sectors, 4 heads, -+ * whatever cylinders. Tell also that data starts at sector. 4. -+ */ -+ geo.cylinders = ( device->size / 4) / 8; /* ?? only for test */ -+ geo.heads = 4; -+ geo.sectors = 8; -+ geo.start = 0; -+ __copy_to_user ( ( void *) arg, &geo, sizeof ( geo)); -+ return 0; -+ -+ default: -+ /* For ioctls we don't understand, let the block layer handle them */ -+ return -ENOTTY; -+ } -+ -+ return -ENOTTY; /* unknown command */ -+} -+ -+static void cf_request( struct request_queue *q) -+{ -+ cf_dev_t *dev; -+ int ret = 0; -+ struct request *req; -+ static int act = 0; -+ -+ if( act) -+ return; -+ -+ act = 1; -+ -+ while( ( req = blk_fetch_request( q)) != NULL){ -+ -+ dev = req->rq_disk->private_data; -+ -+ if( !dev || dev->card_state == CF_CARD_REMOVE){ -+ -+ DEBUG( CF_DEBUG, 1, "CF: locating device error\n"); -+ __blk_end_request_cur( req, -EIO); -+ -+ act = 0; -+ return; -+ } -+ -+ ret = cf_transfer( dev, req); -+ __blk_end_request( req, 0, ret << 9); -+ } -+ -+ act = 0; -+} -+ -+static int cf_dma_ch_alloc(cf_dev_t *dev) -+{ -+ dmad_chreq *ch_req = &dev->ch_req; -+ -+ memset(ch_req, 0, sizeof(dmad_chreq)); -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+ ch_req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */ -+ ch_req->apb_req.addr0_reqn = APBBR_REQN_CFC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ -+ ch_req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */ -+ ch_req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ -+ ch_req->apb_req.burst_mode = 0; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */ -+ ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */ -+ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ -+ -+ ch_req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ -+ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ memset(ch_req, 0, sizeof(dmad_chreq)); -+ printk(KERN_INFO "%s: APB dma channel allocation failed\n", __func__); -+ goto _try_ahb; -+ } -+ -+#if (CF_DEBUG) -+ printk("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); -+#endif -+ -+ return 0; -+ -+_try_ahb: -+ -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ -+ ch_req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */ -+ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */ -+ ch_req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */ -+ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */ -+ ch_req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ -+ ch_req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ -+ ch_req->ahb_req.addr0_reqn = DMAC_REQN_CFC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ -+ ch_req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ -+ ch_req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ -+ ch_req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ -+ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ -+ -+ ch_req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ -+ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ memset(ch_req, 0, sizeof(dmad_chreq)); -+ printk(KERN_INFO "%s: AHB dma channel allocation failed\n", __func__); -+ goto _err_exit; -+ } -+ -+#if (CF_DEBUG) -+ printk("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); -+#endif -+ -+ return 0; -+ -+_err_exit: -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+ return -ENODEV; -+} -+ -+/* -+ * Note no locks taken out here. In a worst case scenario, we could drop -+ * a chunk of system memory. But that should never happen, since validation -+ * happens at open or mount time, when locks are held. -+ */ -+static int cf_revalidate( struct gendisk *gd) -+{ -+ cf_dev_t *dev = gd->private_data; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ dev->card_state = cfc->HostStatus & CARD_DETECT_BIT ? CF_CARD_INSERT : CF_CARD_REMOVE; -+ -+ DEBUG( CF_DEBUG, 1, "card state: %s\n", -+ dev->card_state == CF_CARD_INSERT ? "INSERT" : -+ dev->card_state == CF_CARD_WORK ? "WORK" : "REMOVE"); -+ -+ if( !dev->usage){ -+ -+ if( cf_card_setup(dev) != TRUE){ -+ -+ DEBUG( CF_DEBUG, 1, "cf_card_setup failed\n"); -+ dev->card_state = CF_CARD_REMOVE; -+ -+ return -1; -+ } -+ else { -+ DEBUG( CF_DEBUG, 1, "CFC Driver with DMA Mode\n"); -+ -+ if (cf_card_info.DMAEnable) { -+ /* acquire dma channel */ -+ if (cf_dma_ch_alloc(dev) != 0) { -+ cf_card_info.DMAEnable = FALSE; -+ cf_free( dev); -+ DEBUG( CF_DEBUG, 1, "Request DMA resource failed\n"); -+ return -1; -+ } -+ DEBUG( CF_DEBUG, 1, "Request DMA resource success\n"); -+ } -+ -+ /* SDC interrupt, currently only for HotSwap */ -+ DEBUG( CF_DEBUG, 1, "Request CFC IRQ: %d\n", FTCFC_IRQ); -+ -+ if( request_irq( FTCFC_IRQ, cf_hotswap_interrupt_handler, IRQF_DISABLED, "CF controller", dev) != 0){ -+ -+ DEBUG( CF_DEBUG, 1, "Unable to allocate CFC IRQ: 0x%x\n", FTCFC_IRQ); -+ cf_free( dev); -+ return -1; -+ } -+ -+ /* require io port address for sd controller */ -+ if( request_region( FTCFC_VA_BASE, 0x48, "CF Controller") == NULL){ -+ -+ DEBUG( CF_DEBUG, 1, "request io port of sd controller fail\n"); -+ cf_free( dev); -+ return -1; -+ } -+ -+ dev->card_state = CF_CARD_WORK; -+ } -+ } -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ -+ return 0; -+} -+ -+/* TODO: forbids open for write when WRITE_PROTECT = 1 */ -+static int cf_open( struct block_device *bdev, fmode_t mode) -+{ -+ cf_dev_t *dev= bdev->bd_disk->private_data; /* device information */ -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ if( ( cfc->HostStatus & CARD_DETECT_BIT) != CARD_DETECT_BIT){ -+ -+ DEBUG( CF_DEBUG, 1, "Error: ( ENOMEDIUM)\n"); -+ return -ENOMEDIUM; -+ } -+ -+ if( CFCardInit()){ -+ -+ DEBUG( CF_DEBUG, 1, "root initialize failed\n"); -+ return FALSE; -+ } -+ -+ if( !dev->usage){ -+ -+ dev->media_change = 1; -+ DEBUG( CF_DEBUG, 1, "forced check_disk_change check\n"); -+ check_disk_change( bdev); -+ } -+ else{ -+ dev->media_change = 0; -+ } -+ -+ DEBUG( CF_DEBUG, 1, "set_capacity() to %d blocks ( %d KBytes)\n", dev->size, dev->size >> 1); -+ set_capacity( dev->gd, dev->size); -+ dev->usage++; -+ cf_devices->lba_sec_offset = 0; -+ DEBUG( CF_DEBUG, 1, "dev: 0x%08lx, cf_devices: 0x%08lx\n", ( unsigned long)dev, ( unsigned long)cf_devices); -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ -+ return 0; /* success */ -+} -+ -+static int cf_release( struct gendisk *gd, fmode_t mode) -+{ -+ cf_dev_t *dev = gd->private_data; -+ -+ DEBUG( CF_DEBUG, 1, "Enter\n"); -+ -+ dev->usage--; -+ -+ if( !dev->usage) -+ cf_free( dev); -+ -+ DEBUG( CF_DEBUG, 1, "Exit\n"); -+ -+ return 0; -+} -+ -+static void setup_device( struct cf_dev *dev, int which) -+{ -+ memset ( dev, 0, sizeof ( struct cf_dev)); -+ dev->size = 0; -+ spin_lock_init( &dev->lock); -+ -+ dev->queue = blk_init_queue( cf_request, &dev->lock); -+ -+ if( !dev->queue) -+ goto out_vfree; -+ -+ blk_queue_logical_block_size( dev->queue, hardsect_size); -+ dev->queue->queuedata = dev; -+ -+ dev->card_state = CF_CARD_REMOVE; -+ -+ /* And the gendisk structure. */ -+ dev->gd = alloc_disk( CF_MINORS); -+ if( ! dev->gd){ -+ -+ DEBUG( CF_DEBUG, 1, "alloc_disk failure\n"); -+ goto out_vfree; -+ } -+ -+ dev->gd->flags = GENHD_FL_REMOVABLE | GENHD_FL_SUPPRESS_PARTITION_INFO; -+ dev->gd->major = cf_major; -+ dev->gd->first_minor = which * CF_MINORS; -+ dev->gd->minors = CF_MINORS; -+ dev->gd->fops = &cf_fops; -+ dev->gd->queue = dev->queue; -+ dev->gd->private_data = dev; -+ -+ snprintf ( dev->gd->disk_name, 32, "cpecf%c", which + 'a'); -+ set_capacity( dev->gd, 0); -+ add_disk( dev->gd); -+ -+ return; -+ -+out_vfree: -+ -+ return; -+} -+ -+static int cf_media_changed( struct gendisk *gd) -+{ -+ struct cf_dev *dev = gd->private_data; -+ -+ DEBUG( CF_DEBUG, 1, "cf_media_changed = %d\n", dev->media_change); -+ -+ return dev->media_change; -+} -+ -+struct block_device_operations cf_fops = { -+ -+ .owner = THIS_MODULE, -+ .open = cf_open, -+ .release = cf_release, -+ .ioctl = cf_ioctl, -+ .revalidate_disk = cf_revalidate, -+ .media_changed = cf_media_changed, -+}; -+ -+static int __init cf_module_init( void) -+{ -+ int result= -ENOMEM, i; -+ -+ DEBUG( 1, 0, "Faraday CF controller Driver (DMA mode)\n"); -+ -+ cf_major = register_blkdev( cf_major, DEVICE_NAME); -+ -+ if( cf_major <= 0){ -+ -+ DEBUG( CF_DEBUG, 1, ":unable to get major number\n"); -+ return -EBUSY; -+ } -+ -+ DEBUG( 1, 0, "CF: make node with 'mknod /dev/cpecf b %d 0'\n", cf_major); -+ -+ cf_devices = kzalloc( CF_DEVS * sizeof( cf_dev_t), GFP_KERNEL); -+ -+ if( !cf_devices) -+ goto fail_malloc; -+ -+ for( i = 0; i < CF_DEVS; i++) -+ setup_device( cf_devices + i, i); -+ -+ return 0; -+ -+fail_malloc: -+ -+ if( cf_devices) -+ kfree( cf_devices); -+ -+ unregister_blkdev( cf_major, DEVICE_NAME); -+ -+ return result; -+} -+ -+static void cf_module_cleanup( void) -+{ -+ int i; -+ -+ if( cf_devices){ -+ -+ for( i = 0; i < CF_DEVS; i++){ -+ -+ del_gendisk( cf_devices[i].gd); -+ put_disk( cf_devices[i].gd); -+ -+ if( cf_devices[i].queue) -+ blk_cleanup_queue( cf_devices[i].queue); -+ } -+ -+ kfree( cf_devices); -+ } -+ -+ unregister_blkdev( cf_major, DEVICE_NAME); -+} -+ -+module_init( cf_module_init); -+module_exit( cf_module_cleanup); -+ -+MODULE_AUTHOR( "Faraday Corp."); -+MODULE_LICENSE( "GPL"); -diff -Nur linux-3.4.113.orig/drivers/block/ftcfc010.h linux-3.4.113/drivers/block/ftcfc010.h ---- linux-3.4.113.orig/drivers/block/ftcfc010.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/block/ftcfc010.h 2016-12-01 20:59:24.380613830 +0100 -@@ -0,0 +1,438 @@ -+/* drivers/block/CPECF/ftcfc.h -+ * -+ * Faraday FTCFC010 Device Driver -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * All Rights Reserved -+ */ -+ -+#ifndef _FTCFC_H_ -+#define _FTCFC_H_ -+ -+#define CF_DEBUG 1 -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+#define CF_DEVS 1 /* number of disks */ -+#define CF_MINORS 16 /* minors per disk */ -+#define CF_SECTOR_SIZE 512 /* sector size */ -+ -+/* SD Card State */ -+#define CF_CARD_REMOVE 0 -+#define CF_CARD_INSERT 1 -+#define CF_CARD_WORK 2 -+ -+/* data window register */ -+#define CFC_READ_FIFO_LEN 4 -+#define CFC_WRITE_FIFO_LEN 4 -+ -+/* card type, sd or mmc */ -+#define MEMORY_CARD_TYPE_SD 0 -+#define MEMORY_CARD_TYPE_MMC 1 -+ -+/***************************************************************************** -+ * SYSTEM ERROR_CODE -+ ****************************************************************************/ -+#define ERR_NO_ERROR 0x00000000 -+ -+/* command error */ -+#define ERR_DATA_CRC_ERROR 0x00000100 -+#define ERR_RSP_CRC_ERROR 0x00000200 -+#define ERR_DATA_TIMEOUT_ERROR 0x00000400 -+#define ERR_RSP_TIMEOUT_ERROR 0x00000800 -+ -+#define ERR_WAIT_OVERRUN_TIMEOUT 0x00001000 -+#define ERR_WAIT_UNDERRUN_TIMEOUT 0x00002000 -+#define ERR_WAIT_DATA_CRC_TIMEOUT 0x00004000 -+#define ERR_WAIT_TRANSFER_END_TIMEOUT 0x00008000 -+ -+#define ERR_SEND_COMMAND_TIMEOUT 0x00010000 -+ -+/* using APB DMA error */ -+#define ERR_APBDMA_RSP_ERROR 0x02000000 -+ -+/* -+ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting -+ */ -+#if CF_DEBUG -+#define CFC_TIMEOUT_BASE (HZ/2) /* Unit is 500 ms */ -+#else -+#define CFC_TIMEOUT_BASE (HZ/3) /* Unit is 333 ms */ -+#endif -+ -+typedef struct _cf_cid_t -+{ -+ uint ManufacturerID; -+ uint ApplicationID; -+ unchar ProductName[7]; -+ uint ProductRevisionHigh; -+ uint ProductRevisionLow; -+ uint ProductSerialNumber; -+ uint ManufactureMonth; -+ uint ManufactureYear; -+} cf_cid_t; -+ -+typedef struct _cf_ccf_t -+{ -+ uint CSDStructure; -+ uint MMCSpecVersion; -+ uint TAAC_u; -+ uint NSAC_u; -+ uint TransferSpeed; -+ uint CardCmdClass; -+ uint ReadBlockLength; -+ uint ReadBlockPartial; -+ uint WriteBlockMisalign; -+ uint ReadBlockMisalign; -+ uint DSRImplemant; -+ uint BlockNumber; -+ uint MemorySize; -+ uint VDDReadMin_u; -+ uint VDDReadMax_u; -+ uint VDDWriteMin_u; -+ uint VDDWriteMax_u; -+ uint EraseBlkEnable; -+ uint EraseSectorSize; -+ uint WriteProtectGroupSize; -+ uint WriteProtectGroupEnable; -+ uint WriteSpeedFactor; -+ uint WriteBlockLength; -+ unchar WriteBlockPartial; -+ unchar CopyFlag; -+ unchar PermanentWriteProtect; -+ unchar TemporaryWriteProtect; -+ unchar FileFormat; -+} cf_ccf_t; -+ -+/***************************************************************************** -+ * SD SCR register -+ ****************************************************************************/ -+typedef struct _cf_scr_t -+{ -+ uint Reserved:16; -+ uint SD_BUS_WIDTH:4; -+ uint SD_SECURITY:3; -+ uint DATA_STAT_AFTER_ERASE:1; -+ uint SD_SPEC:4; -+ uint SCR_STRUCTURE:4; -+ -+ uint ManufacturerReserved; -+} cf_scr_t; -+ -+/***************************************************************************** -+ * sd card structure -+ ****************************************************************************/ -+typedef struct _cf_card_t -+{ -+ /* host interface configuration */ -+ uint IOAddr; /* host controller register base address */ -+ uint DMAEnable; -+ uint DMAChannel; -+ -+ uint CardType; -+ -+ uint CIDWord[4]; -+ cf_cid_t CID; -+ -+ uint CSDWord[4]; -+ cf_ccf_t CSD; -+ -+ ushort RCA; -+ cf_scr_t SCR; -+ -+ /* access time out */ -+ uint ReadAccessTimoutCycle; -+ uint WriteAccessTimoutCycle; -+ -+ /* system configurations */ -+ uint SysFrequency; -+ -+ /* card status */ -+ int ActiveState; -+ int WriteProtect; -+ -+ void *private; -+} cf_card_t; -+ -+typedef struct _CF_Dev -+{ -+ u32 dev_size; /* used same as sect_num */ -+ u32 sect_num; /* sector num */ -+ u8 blksize_bit; /* It's not used */ -+ u32 blksize; /* size of block in file system, 1024 */ -+ -+ u32 phy_blksize; /* Physical size of block on the CF. It's not used */ -+ u32 phy_sectorsize; /* the size of erasable sector. It's not used */ -+ u32 wp_grp_size; /* the size of write protected group. It's not used */ -+ -+ spinlock_t lock; /* synchronization */ -+ struct semaphore sema; /* synchronization */ -+ u32 usage; -+ -+ u8 busy; -+ -+ wait_queue_head_t select_wait; /* Kernel thread blocked on it. It's not used */ -+ u8 cmd; /* What command being executed. */ -+ u32 result; /* set by tasklet */ -+ u8 *buff; -+ -+ u32 lba_sec_offset; -+ -+ /*APB_DMA */ -+ -+ u8 DMATransDir; /* 0: IDLE, 1:READ, 2:WRITE */ -+} CF_Dev; -+ -+#define CFC_R_IDLE 0x00 -+#define CFC_R_START_TRANSFER 0x01 -+#define CFC_R_SET_CFCARD_REG 0x02 -+#define CFC_R_SET_CFCARD_READ_CMD 0x03 -+#define CFC_R_CHK_CFCARD_READY 0x04 -+#define CFC_R_SET_DMA_REG 0x05 -+#define CFC_R_DMA_START 0x06 -+#define CFC_R_DMA_INT 0x07 -+#define CFC_R_DMA_FINISH 0x08 -+#define CFC_R_PIO_START 0x09 -+#define CFC_R_PIO_FINISH 0x0A -+#define CFC_R_CHECK_CFCARD_BUSY 0x0B -+#define CFC_R_CHECK_CFCARD_READY 0x0C -+ -+#define CFC_W_IDLE 0x00 -+#define CFC_W_START_TRANSFER 0x10 -+#define CFC_W_SET_CFCARD_REG 0x20 -+#define CFC_W_SET_CFCARD_READ_CMD 0x30 -+#define CFC_W_CHK_CFCARD_READY 0x40 -+#define CFC_W_SET_DMA_REG 0x50 -+#define CFC_W_DMA_START 0x60 -+#define CFC_W_DMA_INT 0x70 -+#define CFC_W_DMA_FINISH 0x80 -+#define CFC_W_PIO_START 0x90 -+#define CFC_W_PIO_FINISH 0xA0 -+#define CFC_W_CHECK_CFCARD_BUSY 0xB0 -+#define CFC_W_CHECK_CFCARD_READY 0xC0 -+ -+#define DMA_IDLE 0x00 -+#define DMA_READ 0x01 -+#define DMA_WRITE 0x02 -+ -+typedef struct CFCTYPE -+{ -+ u32 HostStatus; /* 0x00 */ -+ u32 ControlReg; /* 0x04 */ -+ u32 TimeCfgReg; /* 0x08 */ -+ u32 BuffCtrlReg; /* 0x0C */ -+ u32 BufferData; /* 0x10 */ -+ u32 MultiSector; /* 0x14 */ -+ -+ /* Enchanced Feature */ -+ u32 TransSzMode2En; /* 0x18 */ -+ u32 TransSzMode2Cnt; /* 0x1C */ -+ u32 Reserved[4]; /* 0x20~0x2F is reserved */ -+ u32 Revision; /* 0x30 */ -+ u32 Feature; /* 0x34 (define buffer size) */ -+ -+} CFCTYPE; -+ -+#define cfc ((volatile struct CFCTYPE *) (FTCFC_VA_BASE)) -+ -+typedef struct _tag_CFCardInfo -+{ -+ u32 SectTotal; -+ u8 ConfigOptionReg; -+ u8 ConfigAndStatusReg; -+ u8 PinReplaceReg; -+ u8 SocketCopyReg; -+ -+} CF_CARD_INFO; -+ -+#define CFC_C_Complete 0x00000400 -+#define CFC_B_Ready 0x00000200 -+#define CFC_8bit 0x00000040 -+#define CFC_16bit 0x00000000 -+#define CFC_Reset 0x00000020 -+#define CFC_T_2048 0x000C0000 -+#define CFC_T_1024 0x000B0000 -+#define CFC_T_512 0x000A0000 -+#define CFC_T_256 0x00090000 -+#define CFC_T_128 0x00080000 -+#define CFC_T_64 0x00070000 -+#define CFC_T_32 0x00060000 -+#define CFC_T_16 0x00050000 -+#define CFC_T_8 0x00040000 -+#define CFC_T_4 0x00030000 -+#define CFC_T_2 0x00020000 -+#define CFC_T_1 0x00010000 -+#define CFC_Read 0x00000000 -+#define CFC_Write 0x00008000 -+#define CFC_Increment 0x00004000 -+#define CFC_Attribute 0x00000000 -+#define CFC_Memory 0x00002000 -+#define CFC_IO 0x00003000 -+ -+/* CF status register bit mapping */ -+#define RDY_nIREQ_BIT 0x0001 -+#define CARD_DETECT_BIT 0x0002 -+#define VOL33_SENSE_BIT 0x0004 -+#define VOL40_SENSE_BIT 0x0008 -+#define STATUS_CHANGE_BIT 0x0010 -+#define SPKR_BIT 0x0020 -+#define BUF_ACTIVE_BIT 0x0100 -+#define BUF_DATA_RDY_BIT 0x0200 -+#define INTA_BIT 0x0400 -+#define BUF_SIZE_BITS 0xF000 -+#define INT_CD_BIT 0x10000 -+#define INT_IO_BIT 0x20000 -+ -+/* CF control register bit mapping */ -+#define POWER_CONTROL_BIT 0x000F -+#define FLOW_CONTROL_BIT 0x0010 -+#define RESET_BIT 0x0020 -+#define MODE_BIT 0x0040 -+#define DMA_BIT 0x0100 -+ -+#define PWR_ON 1 -+#define PWR_OFF 0 -+ -+#define SIGNAL_ON 0x0010 -+#define SIGNAL_OFF 0x0000 -+ -+#define BYTE_MODE 0x0040 -+#define WORD_MODE 0x0000 -+ -+#define ENDMA_BIT 0x0100 -+#define DISDMA_BIT 0x0000 -+ -+#define CARD_DETECT_INT_MASK 0x0200 -+#define DATA_CMP_INT_MASK 0x0400 -+#define IO_INT_MASK 0x0800 -+ -+/* active buffer control register bit mapping */ -+#define ADR_BIT 0x007FF -+#define TYPE_BIT 0x03000 -+#define INCADR_BIT 0x04000 -+#define RW_BIT 0x08000 -+#define TRANS_SIZE_CONTROL_BIT 0xF0000 -+ -+#define INCADR 0x04000 -+#define NOINCADR 0x00000 -+#define TRANS_SIZE_LOC 16 -+ -+#define SIZE_1_BYTE 0x01 -+#define SIZE_2_BYTE 0x02 -+#define SIZE_4_BYTE 0x03 -+#define SIZE_8_BYTE 0x04 -+#define SIZE_16_BYTE 0x05 -+#define SIZE_32_BYTE 0x06 -+#define SIZE_64_BYTE 0x07 -+#define SIZE_128_BYTE 0x08 -+#define SIZE_256_BYTE 0x09 -+#define SIZE_512_BYTE 0x0a -+#define SIZE_1024_BYTE 0x0b -+#define SIZE_2048_BYTE 0x0c -+ -+#define READ_OP 0x00000 -+#define WRITE_OP 0x08000 -+ -+/* type description */ -+#define ATTRIBUTE_MEM 0x00000 -+#define COMMON_MEM 0x02000 -+ -+/* -+ * CF card -+ * memory map register -+ * IO block register -+ */ -+#define BLKMEM_DATA_REG 0x000 -+#define BLKMEM_ERROR_REG ( BLKMEM_DATA_REG + 0x01) -+#define BLKMEM_FEATURE_REG ( BLKMEM_DATA_REG + 0x01) -+#define BLKMEM_SECTOR_COUNT_REG ( BLKMEM_DATA_REG + 0x02) -+#define BLKMEM_SECTOR_NUMBER_REG ( BLKMEM_DATA_REG + 0x03) -+#define BLKMEM_CYLINDER_LOW_REG ( BLKMEM_DATA_REG + 0x04) -+#define BLKMEM_CYLINDER_HIGH_REG ( BLKMEM_DATA_REG + 0x05) -+#define BLKMEM_DRIVE_REG ( BLKMEM_DATA_REG + 0x06) -+#define BLKMEM_STATUS_REG ( BLKMEM_DATA_REG + 0x07) -+#define BLKMEM_COMMAND_REG ( BLKMEM_DATA_REG + 0x07) -+ -+#define BLKMEM_EVEN_DATA_REG ( BLKMEM_DATA_REG + 0x08) -+#define BLKMEM_ODD_DATA_REG ( BLKMEM_DATA_REG + 0x09) -+#define BLKMEM_DUP_ERROR_REG ( BLKMEM_DATA_REG + 0x0d) -+#define BLKMEM_DUP_FEATURE_REG ( BLKMEM_DATA_REG + 0x0d) -+#define BLKMEM_DEV_CONTROL_REG ( BLKMEM_DATA_REG + 0x0e) -+#define BLKMEM_DRIVE_ADDR_REG ( BLKMEM_DATA_REG + 0x0f) -+#define BLKMEM_WINDOW_REG ( BLKMEM_DATA_REG + 0x400) -+#define BLKMEM_MAX_WINDOW_REG ( BLKMEM_DATA_REG + 0x7ff) -+ -+/* status register */ -+#define BUSY_BIT 0x80 -+#define RDY_BIT 0x40 -+#define DWF_BIT 0x20 -+#define DSC_BIT 0x10 -+#define DRQ_BIT 0x08 -+#define CORR_BIT 0x04 -+#define ERR_BIT 0x01 -+ -+/* CF ATA command */ -+#define ATA_CHECK_POWER_MODE 0xe5 -+#define ATA_EXECUTE_DRIVE_DIAG 0x90 -+#define ATA_ERASE_SECTOR 0xc0 -+#define ATA_FORMAT_TRACK 0x50 -+#define ATA_IDENTIFY_DRIVE 0xec -+#define ATA_IDLE 0xe3 -+#define ATA_IDLE_IMMEDIATE 0xe1 -+#define ATA_INIT_DRIVE_PARA 0x91 -+#define ATA_READ_BUFFER 0xe4 -+#define ATA_READ_LONG_SECTOR 0x22 -+#define ATA_READ_MULTIPLE 0xc4 -+#define ATA_READ_SECTOR 0x21 -+#define ATA_READ_VERIFY_SECTOR 0x40 -+#define ATA_RECALIBRATE 0x10 -+#define ATA_REQUEST_SENSE 0x03 -+#define ATA_SECURITY_DISABLE_PASSWORD 0xf6 -+#define ATA_SECURITY_EREASE_PREPARE 0xf3 -+#define ATA_SECURITY_ERASE_UNIT 0xf4 -+#define ATA_SECURITY_FREEZE_LOCK 0xf5 -+#define ATA_SECURITY_SET_PASSWORD 0xf1 -+#define ATA_SECURITY_UNLOCK 0xf2 -+#define ATA_SEEK 0x70 -+#define ATA_SET_FEATURE 0xef -+#define ATA_SET_MULTIPLE_MODE 0xc6 -+#define ATA_SET_SLEEP_MODE 0xe6 -+#define ATA_STANDBY 0xe2 -+#define ATA_STANDBY_IMMEDIATE 0xe0 -+#define ATA_TRANSFER_SECTOR 0x87 -+#define ATA_WEAR_LEVEL 0xf5 -+#define ATA_WRITE_BUFFER 0xe8 -+#define ATA_WRITE_LONG_SECTOR 0x32 -+#define ATA_WRITE_MULTIPLE 0xc5 -+#define ATA_WRITE_MULTIPLE_WO_ERASE 0xcd -+#define ATA_WRITE_SECTOR 0x30 -+#define ATA_WRITE_SECTOR_WO_ERASE 0x38 -+#define ATA_WRITE_VERIFY 0x3c -+ -+#define CF_MEM_MAP_MODE 0x0 -+/* attribute memory space register description */ -+#define ATTRIBUTE_MEM_BASE 0 -+#define ATTRIBUTE_MEM_CONFIG_BASE 0x200 -+#define CONFIG_OPTION_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x00) -+#define CARD_CONFIG_STATUS_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x02) -+#define PIN_REPLACE_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x04) -+#define SOCKET_COPY_REG ( ATTRIBUTE_MEM_CONFIG_BASE + 0x06) -+ -+/* configuration option register */ -+#define CONF0_BIT 0x01 -+#define CONF1_BIT 0x02 -+#define CONF2_BIT 0x04 -+#define CONF3_BIT 0x08 -+#define CONF4_BIT 0x10 -+#define CONF5_BIT 0x20 -+#define LEVLREQ_BIT 0x40 -+#define SRESET_BIT 0x80 -+ -+#endif -diff -Nur linux-3.4.113.orig/drivers/block/ftsdc010.c linux-3.4.113/drivers/block/ftsdc010.c ---- linux-3.4.113.orig/drivers/block/ftsdc010.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/block/ftsdc010.c 2016-12-01 20:59:24.384613985 +0100 -@@ -0,0 +1,2206 @@ -+/* drivers/block/CPESD/ftsdc010.c -+ ******************************************************************************* -+ * Faraday FTSDC010 Device Driver -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * All Rights Reserved -+ * -+ * Porting to Linux 2.6 on 20050815 -+ * Author: Chris Lee, I-Jui Sung, Peter Liao (support APB DMA) -+ * Version: 0.2 -+ * History: -+ * 0.1 new creation -+ * 0.2 Porting to meet the style of linux dma -+ * 0.3 modify dma usage to virtual irq of dma interrupt -+ * 0.4 (20050701) Improve r/w performance -+ * 0.5 Porting to Linux 2.6 and replace busy_loop checking with timer's timeout -+ * Todo: -+ ******************************************************************************* -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include /* HDIO_GETGEO */ -+#include -+#include -+#include /* invalidate_bdev */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define IPMODULE SDC -+#define IPNAME FTSDC010 -+ -+/* Define CONFIG_FTSDC010_USE_TIMER_DELAY if you want to use software timer instead of busy loop checking */ -+#define CONFIG_FTSDC010_USE_TIMER_DELAY -+#undef CONFIG_FTSDC010_USE_TIMER_DELAY -+#include "ftsdc010.h" -+#include -+MODULE_AUTHOR("Faraday Corp."); -+MODULE_LICENSE("Faraday License"); -+ -+/* options */ -+#define FORCE_PCI_CONSISTENCY 1 /* define it to 1 if met consistency problems */ -+#define KERNEL_SECTOR_SIZE 512 /* Use this when we refer to kernel related sector size */ -+ -+static int hardsect_size = 512; -+module_param(hardsect_size, int, 0); -+/*------------------------------------------------------------------------------ -+ * Predefine for block device -+ */ -+#define MAJOR_NR sd_major /* force definitions on in blk.h */ -+static int sd_major=0;//SD_MAJOR; /* must be declared before including blk.h */ -+#define SD_SHIFT 4 /* max 16 partitions */ -+#define DEVICE_NAME "Faraday SDC" /* name for messaging */ -+#define DEVICE_REQUEST sd_request -+#define DEVICE_NR(device) (MINOR(device) >> SD_SHIFT) -+//#define DEVICE_INTR sd_intrptr /* pointer to the bottom half */ -+#define DEVICE_NO_RANDOM /* no entropy to contribute */ -+#define DEVICE_OFF(d) /* do-nothing */ -+ -+/*#include -+#include */ /* blk_ioctl() */ -+ -+/*------------------------------------------------------------------------------ -+ * Macro definition -+ */ -+#define FTSDC_VA_BASE IP_VA_BASE(0) -+#define FTSDC_PA_BASE IP_PA_BASE(0) -+#define FTSDC_IRQ IP_IRQ(0) -+#define SDC_W_REG(offset, value) outl(value, IP_VA_BASE(0) + offset) -+#define SDC_R_REG(offset) inl(IP_VA_BASE(0) + offset) -+ -+ -+/*------------------------------------------------------------------------------ -+ * Global variable -+ */ -+ -+/* The following items are obtained through kmalloc() in sd_module_init() */ -+ -+struct block_device_operations sd_fops; -+/* our device structure */ -+struct sd_dev { -+ int size; /* device size in sectors */ -+ int usage; /* # of users currently */ -+ int media_change; /* Flag: media changed? */ -+ struct gendisk *gd; /* The gendisk structure */ -+ spinlock_t lock; /* For mutual exclusion */ -+ struct request_queue *queue; /* The device request queue */ -+ int card_state; -+ dmad_chreq ch_req; -+ bool dma_enable; -+}; -+static struct sd_dev *sd_devices = NULL; -+ -+static sd_card_t sd_card_info; -+static int sector_offset,Do_onetime; -+ -+dma_addr_t dma_buf = 0; /* ?? non-zero for for manually debug ?? */ -+struct completion sd_dma_cmpl; -+ -+static int sync_mode=0; -+ -+static uint first_run = 0; -+uint sd_err_code; -+ -+#define FILE_FORMAT_HARD_DISK_LIKE 0 -+#define FILE_FORMAT_FLOPPY_LIKE 1 -+#define FILE_FORMAT_UNIVERSAL 2 -+#define FILE_FORMAT_UNKNOW 3 -+#define FILE_FORMAT_RESERVED 4 -+ -+#define K 1000 -+ -+uint TAAC_TimeUnitTable[] = { // unit is ns -+ 1, 10, 100, 1 * K, 10 * K, 100 * K, 1 * K * K, 10 * K * K -+}; -+ -+uint TRANS_SPEED_RateUintTable[] = { -+ 100 * K, 1 * K * K, 10 * K * K, 100 * K * K -+}; -+ -+uint TRANS_SPEED_TimeValueTable_u[] = { // unit=1/10 -+ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 -+}; -+ -+uint VDD_CURR_MIN_Table_u[] = { // unit=1/10 -+ 5, 10, 50, 100, 250, 350, 600, 1000 -+}; -+ -+uint VDD_CURR_MAX_Table_u[] = { -+ 1, 5, 10, 25, 35, 45, 80, 200 -+}; -+ -+uint TAAC_TimeValueTable_u[] = { // unit=1/10 -+ 0, 10, 12, 13, 15, 20, 25, 30, 35, 40, 45, 50, 55, 60, 70, 80 -+}; -+ -+ -+unsigned int SDC_READ_FIFO_LEN; -+unsigned int SDC_WRITE_FIFO_LEN; -+ -+/*------------------------------------------------------------------------------ -+ * Local declaration of function -+ */ -+static int sd_revalidate(struct gendisk *gd); -+static int sd_media_changed(struct gendisk *gd); -+static int sd_card_setup(struct sd_dev *dev); -+int sd_check_err(uint status); -+int sd_get_scr(sd_card_t *info, uint *scr); -+int sd_set_transfer_state(sd_card_t *info); -+uint sd_block_size_convert(uint size); -+int sd_read_sector(sd_card_t *info, uint addr, uint count, unchar *buf); -+void sd_reset_host_controller(void); -+/*------------------------------------------------------------------------------ -+ * Local function -+ */ -+ -+/* -+ * SD host controller operation -+ */ -+int sdc_send_cmd(uint cmd, uint arg, uint *rsp) -+{ -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+ int count = 0; -+#else -+ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; -+#endif -+ int i; -+ uint status; -+ P_DEBUG("SD Cmd is %d\n",cmd); -+ -+ /* clear command relative bits of status register */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_FAIL | SDC_STATUS_REG_RSP_TIMEOUT | SDC_STATUS_REG_RSP_CRC_OK| SDC_STATUS_REG_CMD_SEND); -+ /* write argument to arugument register if necessary */ -+ SDC_W_REG(SDC_ARGU_REG, arg); -+ /* send command */ -+ SDC_W_REG(SDC_CMD_REG, cmd | SDC_CMD_REG_CMD_EN); -+ -+ /* wait for the CMD_SEND bit of status register is set */ -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { -+#else -+ while (time_before(jiffies, timeout)) { -+#endif -+ status = SDC_R_REG(SDC_STATUS_REG); -+ if (!(cmd & SDC_CMD_REG_NEED_RSP)) { -+ /* if this command does not need response, wait command sent flag */ -+ if (status & SDC_STATUS_REG_CMD_SEND) { -+ /* clear command sent bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CMD_SEND); -+ sd_err_code = ERR_NO_ERROR; -+ return TRUE; -+ } -+ } else { -+ /* if this command needs response */ -+ if (status & SDC_STATUS_REG_RSP_TIMEOUT) { -+ /* clear response timeout bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_TIMEOUT); -+ sd_err_code = ERR_RSP_TIMEOUT_ERROR; -+ printk("%s() ERR_RSP_TIMEOUT_ERROR\n", __func__); -+ return FALSE; -+ } else if (status & SDC_STATUS_REG_RSP_CRC_FAIL) { -+ /* clear response fail bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_FAIL); -+ sd_err_code = ERR_RSP_CRC_ERROR; -+ printk("%s() ERR_RSP_CRC_ERROR\n", __func__); -+ return FALSE; -+ } else if (status & SDC_STATUS_REG_RSP_CRC_OK) { -+ /* clear response OK bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_RSP_CRC_OK); -+ /* if it is long response */ -+ if (cmd & SDC_CMD_REG_LONG_RSP) -+ for (i = 0; i < 4; i++, rsp++) -+ *rsp = SDC_R_REG(SDC_RESPONSE0_REG + (i * 4)); -+ else -+ *rsp = SDC_R_REG(SDC_RESPONSE0_REG); -+ sd_err_code = ERR_NO_ERROR; -+ return TRUE; -+ } -+ } -+ } -+ sd_err_code = ERR_SEND_COMMAND_TIMEOUT; -+ P_DEBUG("%s() ERR_SEND_COMMAND_TIMEOUT\n", __func__); -+ return FALSE; -+} -+ -+int sdc_check_tx_ready(void) -+{ -+ uint status; -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+ int count = 0; -+ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { -+#else -+ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; -+ while (time_before(jiffies, timeout)) { -+#endif -+ status = SDC_R_REG(SDC_STATUS_REG); -+ if (status & SDC_STATUS_REG_FIFO_UNDERRUN) { -+ /* clear FIFO underrun bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_FIFO_UNDERRUN); -+ return TRUE; -+ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { -+ /* clear data timeout bit */ -+ printk("Wait Write FIFO TimeOut\n"); -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); -+ sd_err_code = ERR_DATA_TIMEOUT_ERROR; -+ return FALSE; -+ } -+ } -+ sd_err_code = ERR_WAIT_UNDERRUN_TIMEOUT; -+ P_DEBUG("%s() ERR_WAIT_UNDERRUN_TIMEOUT\n", __func__); -+ return FALSE; -+} -+ -+int sdc_check_rx_ready(void) -+{ -+ uint status; -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+ int count = 0; -+ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { -+#else -+ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; -+ while (time_before(jiffies, timeout)) { -+#endif -+ status = SDC_R_REG(SDC_STATUS_REG); -+ if (status & SDC_STATUS_REG_FIFO_OVERRUN) { -+ /* clear FIFO overrun bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_FIFO_OVERRUN); -+ return TRUE; -+ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { -+ /* clear data timeout bit */ -+ printk("Wait Read FIFO TimeOut\n"); -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); -+ sd_err_code = ERR_DATA_TIMEOUT_ERROR; -+ return FALSE; -+ } -+ } -+ sd_err_code = ERR_WAIT_OVERRUN_TIMEOUT; -+ P_DEBUG("%s() ERR_WAIT_OVERRUN_TIMEOUT\n", __func__); -+ return FALSE; -+} -+ -+int sdc_check_data_crc(void) -+{ -+ uint status=0; -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+ int count = 0; -+ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { -+#else -+ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; -+ while (time_before(jiffies, timeout)) { -+#endif -+ status = SDC_R_REG(SDC_STATUS_REG); -+ if (status & SDC_STATUS_REG_DATA_CRC_OK) { -+ P_DEBUGG("%s : receive data ok, status=0x%x\n", __func__, status); -+ /* clear data CRC OK bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_CRC_OK); -+ return TRUE; -+ } else if (status & SDC_STATUS_REG_DATA_CRC_FAIL) { -+ /* clear data CRC fail bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_CRC_FAIL); -+ sd_err_code = ERR_DATA_CRC_ERROR; -+ printk("%s() ERR_DATA_CRC_ERROR\n", __func__); -+ return FALSE; -+ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { -+ /* clear data timeout bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); -+ sd_err_code = ERR_DATA_TIMEOUT_ERROR; -+ printk("%s() ERR_DATA_TIMEOUT_ERROR\n", __func__); -+ return FALSE; -+ } -+ } -+ P_DEBUG("%s() ERR_WAIT_DATA_CRC_TIMEOUT, status=0x%x\n", __func__, status); -+ sd_err_code = ERR_WAIT_DATA_CRC_TIMEOUT; -+ return FALSE; -+} -+ -+static inline int sdc_check_data_end(void) -+{ -+ uint status; -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+ int count = 0; -+ while (count++ < SDC_GET_STATUS_RETRY_COUNT) { -+#else -+ unsigned long timeout = jiffies + SDC_GET_STATUS_RETRY_TIMEOUT_COUNT; -+ while (time_before(jiffies, timeout)) { -+#endif -+ status = SDC_R_REG(SDC_STATUS_REG); -+ if (status & SDC_STATUS_REG_DATA_END) { -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_END); -+ return TRUE; -+ } else if (status & SDC_STATUS_REG_DATA_TIMEOUT) { -+ /* clear data timeout bit */ -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_DATA_TIMEOUT); -+ sd_err_code = ERR_DATA_TIMEOUT_ERROR; -+ printk("%s() ERR_DATA_TIMEOUT_ERROR\n", __func__); -+ return FALSE; -+ } -+ } -+ sd_err_code = ERR_WAIT_TRANSFER_END_TIMEOUT; -+ P_DEBUG("%s() ERR_WAIT_TRANSFER_END_TIMEOUT\n", __func__); -+ return FALSE; -+} -+ -+int sdc_set_bus_width_cmd(sd_card_t *info, uint width) -+{ -+ uint status; -+ -+ /* send CMD55 to indicate to the card that the next command is an application specific command */ -+ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, (((uint)info->RCA) << 16), &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ /* send ACMD6 to set bus width */ -+ if (!sdc_send_cmd(SD_SET_BUS_WIDTH_CMD | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, width, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+int sdc_set_bus_width(sd_card_t *info) -+{ -+ uint width; -+ -+ /* if it is not SD card, it does not support wide bus */ -+ if (info->CardType != MEMORY_CARD_TYPE_SD) -+ return TRUE; -+ /* get SCR register */ -+ if (!sd_get_scr(info, (uint *) &info->SCR)) -+ return FALSE; -+ /* if host controller does not support wide bus, return */ -+ if ((SDC_R_REG(SDC_BUS_WIDTH_REG) & SDC_WIDE_BUS_SUPPORT) != SDC_WIDE_BUS_SUPPORT) -+ return TRUE; -+ if (!sd_set_transfer_state(info)) -+ return FALSE; -+ if (info->SCR.SD_BUS_WIDTH & SD_SCR_4_BIT_BIT) -+ width = SD_BUS_WIDTH_4_BIT; -+ else -+ width = SD_BUS_WIDTH_1_BIT; -+ if (!sdc_set_bus_width_cmd(info, width)) -+ return FALSE; -+ if (width == SD_BUS_WIDTH_1_BIT) -+ SDC_W_REG(SDC_BUS_WIDTH_REG, SDC_BUS_WIDTH_REG_SINGLE_BUS); -+ else -+ SDC_W_REG(SDC_BUS_WIDTH_REG, SDC_BUS_WIDTH_REG_WIDE_BUS); -+ -+ return TRUE; -+} -+ -+static inline int sdc_pre_erase_cmd(uint nr_blocks) -+{ -+ uint status; -+ sd_card_t *info=&sd_card_info; -+ /* send CMD55 to indicate to the card that the next command is an application specific command */ -+ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, (((uint)info->RCA) << 16), &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ /* send ACMD6 to set bus width */ -+ if (!sdc_send_cmd(23 | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, nr_blocks, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+ -+uint sdc_set_bus_clock(sd_card_t *info, uint clock) -+{ -+ uint div = 0, reg; -+ -+ while (clock < (info->SysFrequency / (2 * (div + 1)))) -+ div++; -+ /* write clock divided */ -+ reg = SDC_R_REG(SDC_CLOCK_CTRL_REG); -+ reg &= (~SDC_CLOCK_REG_CLK_DIV | 0x80); //ijsung: preserv SD or MMC -+ reg += div & SDC_CLOCK_REG_CLK_DIV; -+ SDC_W_REG(SDC_CLOCK_CTRL_REG, reg); -+ P_DEBUG("%s: SD clock=%d, info->SysFrequency=%d, div=%d\n",__func__,clock, info->SysFrequency, div); -+ return info->SysFrequency / (2 * (div + 1)); -+} -+ -+static inline int sdc_set_block_size(uint size) -+{ -+ uint status; -+ static uint last_size=0; -+ if (size == last_size) -+ return TRUE; -+ else -+ last_size=size; -+ -+ if (!sdc_send_cmd(SD_SET_BLOCKLEN_CMD | SDC_CMD_REG_NEED_RSP, size, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ return TRUE; -+} -+ -+void sdc_set_card_type(int type) -+{ -+ uint reg; -+ -+ reg = SDC_R_REG(SDC_CLOCK_CTRL_REG); -+ reg &= ~SDC_CLOCK_REG_CARD_TYPE; -+ -+ if (type == MEMORY_CARD_TYPE_SD) { -+ reg |= SDC_CARD_TYPE_SD; -+ } -+ else { -+ reg |= SDC_CARD_TYPE_MMC; -+ } -+ -+ SDC_W_REG(SDC_CLOCK_CTRL_REG, reg); -+} -+ -+int sdc_read_block(sd_card_t *info, uint size, uint *buf) -+{ -+ /* -+ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting -+ */ -+ unsigned long timeout = jiffies + SDC_TIMEOUT_BASE*((size+511)>>9); -+ uint count, i; -+ dmad_chreq *ch_req = (dmad_chreq *)info->private; -+ dmad_drb *drb = 0; -+ u32 drb_size = 0; -+ dma_addr_t addr_iter; -+ -+ //if (info->DMAEnable) { -+ if ((info->DMAEnable) && ((size & 0xf) == 0)) { -+ P_DEBUG("%s:size=%d, buf=%p) - DMA Read\n", __func__, size,buf ); -+ P_DEBUG("dma_buf = %d\n", dma_buf); -+ -+ init_completion(&sd_dma_cmpl); -+ -+ if (dma_buf) -+ consistent_sync(__va(dma_buf), size, DMA_FROM_DEVICE); -+ else -+ consistent_sync(buf, size, DMA_FROM_DEVICE); -+ -+ //prepare parameter for add dma entry -+ dmad_config_channel_dir(ch_req, DMAD_DIR_A0_TO_A1); -+ -+ drb_size = dmad_max_size_per_drb(ch_req); -+ -+ if (dma_buf) -+ addr_iter = dma_buf; // given dest phy addr -+ else -+ addr_iter = __pa(buf); -+ -+ while (size > 0) { -+ -+ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { -+ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); -+ return FALSE; -+ } -+ -+ drb->addr0 = FTSDC_PA_BASE + SDC_DATA_WINDOW_REG; -+ drb->addr1 = addr_iter; -+ -+ if (size <= drb_size) { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); -+ drb->sync = &sd_dma_cmpl; -+ size = 0; -+ } else { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); -+ drb->sync = 0; -+ size -= drb_size; -+ addr_iter += drb_size; -+ } -+ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); -+ -+ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { -+ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); -+ return FALSE; -+ } -+ } -+ -+ if (wait_for_completion_timeout(&sd_dma_cmpl, timeout - jiffies) == 0) -+ printk("%s: read timeout\n", __func__); -+ } else { -+ while (size > 0) { -+ if (!sdc_check_rx_ready()) { -+ printk("error...........\n"); -+ return FALSE; -+ } -+ /* read data from FIFO */ -+ if (size >= (SDC_READ_FIFO_LEN << 2)) -+ count = SDC_READ_FIFO_LEN; -+ else -+ count = size >> 2; -+ /* read data from FIFO */ -+ P_DEBUG("\n"); -+ for (i = 1; i <= count; i++, buf++) -+ { -+ *buf = SDC_R_REG(SDC_DATA_WINDOW_REG); -+ P_DEBUG("%.8x ",*buf); -+ } -+ size -= (count << 2); -+ } -+ } -+ return sdc_check_data_crc(); -+} -+ -+int sdc_write_block(sd_card_t *info, uint size, uint *buf) -+{ -+ unsigned long timeout = jiffies + SDC_TIMEOUT_BASE*3*((size+511)>>9); -+ uint count, i; -+ dmad_chreq *ch_req = (dmad_chreq *)info->private; -+ dmad_drb *drb = 0; -+ u32 drb_size = 0; -+ dma_addr_t addr_iter; -+ -+ //if (info->DMAEnable) { -+ if ((info->DMAEnable) && ((size & 0xf) == 0)) { -+ P_DEBUG("%s:size=%d, buf=%p) - DMA Write\n", __func__, size,buf ); -+ -+ init_completion(&sd_dma_cmpl); -+ -+ if (dma_buf) -+ consistent_sync(__va(dma_buf), size, DMA_TO_DEVICE); -+ else -+ consistent_sync(buf, size, DMA_TO_DEVICE); -+ -+ //prepare parameter for add dma entry -+ dmad_config_channel_dir(ch_req, DMAD_DIR_A1_TO_A0); -+ -+ drb_size = dmad_max_size_per_drb(ch_req); -+ -+ if (dma_buf) -+ addr_iter = dma_buf; // given dest phy addr -+ else -+ addr_iter = __pa(buf); -+ -+ while (size > 0) { -+ -+ if (unlikely(0 != dmad_alloc_drb(ch_req, &drb) || (drb == 0))) { -+ printk(KERN_ERR "%s() Failed to allocate dma request block!\n", __func__); -+ return FALSE; -+ } -+ -+ drb->addr0 = FTSDC_PA_BASE + SDC_DATA_WINDOW_REG; -+ drb->addr1 = addr_iter; -+ -+ if (size <= drb_size) { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, size); -+ drb->sync = &sd_dma_cmpl; -+ size = 0; -+ } else { -+ drb->req_cycle = dmad_bytes_to_cycles(ch_req, drb_size); -+ drb->sync = 0; -+ size -= drb_size; -+ addr_iter += drb_size; -+ } -+ //printk(KERN_INFO "%s() size_remain 0x%08x.\n", __func__, size); -+ -+ if (unlikely(0 != dmad_submit_request(ch_req, drb, 1))) { -+ printk(KERN_ERR "%s() Failed to submit dma request block!\n", __func__); -+ return FALSE; -+ } -+ } -+ -+ if (wait_for_completion_timeout(&sd_dma_cmpl, timeout - jiffies) == 0) -+ printk("write timeout\n"); -+ } else { -+ while (size > 0) { -+ if (!sdc_check_tx_ready()) -+ return FALSE; -+ /* write data from FIFO */ -+ if (size >= (SDC_WRITE_FIFO_LEN << 2)) -+ count = SDC_WRITE_FIFO_LEN; -+ else -+ count = (size >> 2) ; -+ /* write data from FIFO */ -+ for (i = 0; i < count; i++, buf++) -+ SDC_W_REG(SDC_DATA_WINDOW_REG, *buf); -+ size -= (count << 2); -+ } -+ } -+ return sdc_check_data_crc(); -+} -+ -+void sdc_config_transfer(sd_card_t *SDCard, uint len, uint size, uint rw, uint timeout) -+{ -+ u32 con; -+ /* write timeout */ -+ SDC_W_REG(SDC_DATA_TIMER_REG, timeout * 2); -+ /* set data length */ -+ SDC_W_REG(SDC_DATA_LEN_REG, len); -+ -+ /* set data block */ -+ if (SDCard->DMAEnable) { -+ con = sd_block_size_convert(size) | SDC_DATA_CTRL_REG_DMA_EN | rw | SDC_DATA_CTRL_REG_DATA_EN; -+ con |= SDC_DMA_TYPE_4; -+ P_DEBUG("%s() transfer DMA mode\n", __func__); -+ SDC_W_REG(SDC_DATA_CTRL_REG, con); -+ } else { -+ P_DEBUG("%s() transfer nonDMA mode\n", __func__); -+ SDC_W_REG(SDC_DATA_CTRL_REG, sd_block_size_convert(size) | rw | SDC_DATA_CTRL_REG_DATA_EN); -+ } -+} -+ -+/* Note: This funciton may be called by interrupt handler */ -+void sdc_reset(void) -+{ -+ uint ret; -+ unsigned long delay = jiffies + (HZ/10)*3; //Delay 300ms -+ -+ /* reset host interface */ -+ SDC_W_REG(SDC_CMD_REG, SDC_CMD_REG_SDC_RST); -+ -+ /* loop, until the reset bit is clear */ -+ do { -+ ret = SDC_R_REG(SDC_CMD_REG); -+ } while ((ret & SDC_CMD_REG_SDC_RST) != 0); -+ #if 0 -+ udelay(1000); -+ #else -+ while(time_before(jiffies, delay)); -+ #endif -+} -+ -+/* -+ * SD card operation -+ */ -+void sd_endian_change(uint *dt, int len) -+{ -+ uint ul; -+ -+ for(; len > 0; len--, dt++) { -+ ul = *dt; -+ ((unchar *)dt)[0] = ((unchar *)&ul)[3]; -+ ((unchar *)dt)[1] = ((unchar *)&ul)[2]; -+ ((unchar *)dt)[2] = ((unchar *)&ul)[1]; -+ ((unchar *)dt)[3] = ((unchar *)&ul)[0]; -+ } -+} -+ -+int sd_get_ocr(sd_card_t *info, uint hocr, uint *cocr) -+{ -+ uint status; -+ int count = 0; -+ -+ do { -+ if (info->CardType == MEMORY_CARD_TYPE_SD) { -+ /* send CMD55 to indicate to the card that the next command is an application specific command */ -+ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ /* send ACMD41 to get OCR register */ -+ if (!sdc_send_cmd(SD_APP_OP_COND | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, (uint) hocr, (uint *) cocr)) -+ return FALSE; -+ } else { -+ /* send CMD1 to get OCR register */ -+ if (!sdc_send_cmd(SD_MMC_OP_COND | SDC_CMD_REG_NEED_RSP, (uint) hocr, (uint *) cocr)) -+ return FALSE; -+ } -+ if (count++ > SD_CARD_GET_OCR_RETRY_COUNT) { -+ sd_err_code = ERR_SD_CARD_IS_BUSY; -+ printk("%s : ERR_SD_CARD_IS_BUSY\n", __func__); -+ return FALSE; -+ } -+ udelay(1000); /* According to spec, at most 1 msec or 74 clock cycles */ -+ } while ((*cocr & SD_OCR_BUSY_BIT) != SD_OCR_BUSY_BIT); -+ -+ return TRUE; -+} -+ -+int sd_get_scr(sd_card_t *info, uint *scr) -+{ -+ uint status; -+ -+ if (!sd_set_transfer_state(info)) -+ return FALSE; -+ if (!sdc_set_block_size(8)) -+ return FALSE; -+ sdc_config_transfer(info, 8, 8, SDC_DATA_CTRL_REG_DATA_READ, 0xFFFFFFFF); -+ /* send CMD55 to indicate to the card that the next command is an application specific command */ -+ if (!sdc_send_cmd(SD_APP_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ /* send ACMD51 to get SCR */ -+ if (!sdc_send_cmd(SD_SEND_SCR_CMD | SDC_CMD_REG_APP_CMD | SDC_CMD_REG_NEED_RSP, 0, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ if (!sdc_read_block(info, 8, (uint *) scr)) -+ return FALSE; -+ if (!sdc_check_data_end()) -+ return FALSE; -+ sd_endian_change(scr, 2); -+ -+ return TRUE; -+} -+ -+int sd_check_err(uint status) -+{ -+ if (status & SD_STATUS_ERROR_BITS) { -+ sd_err_code = ERR_SD_CARD_STATUS_ERROR; -+ printk("%s() ERR_SD_CARD_STATUS_ERROR %X\n", __func__, status); -+ return FALSE; -+ } -+ sd_err_code = ERR_NO_ERROR; -+ return TRUE; -+} -+ -+int sd_get_card_state(sd_card_t *info, uint *ret) -+{ -+ uint status; -+ -+ /* send CMD13 to get card status */ -+ if (!sdc_send_cmd(SD_SEND_STATUS_CMD | SDC_CMD_REG_NEED_RSP, ((uint) info->RCA) << 16, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ *ret = (status & SD_STATUS_CURRENT_STATE) >> SD_STATUS_CURRENT_STATE_LOC; -+ return TRUE; -+} -+ -+int sd_operation_complete(sd_card_t *info, uint finish) -+{ -+ uint state; -+ int count = 0; -+ while (count++ < SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT) { -+ if (!sd_get_card_state(info, &state)) -+ return FALSE; -+ if (state == finish) -+ return TRUE; -+ } -+ P_DEBUG("%s() error\n", __func__); -+ return FALSE; -+} -+ -+int sd_stop_transmission(void) -+{ -+ uint status; -+ -+ /* send CMD12 to stop transmission */ -+ if (!sdc_send_cmd(SD_STOP_TRANSMISSION_CMD | SDC_CMD_REG_NEED_RSP, 0, &status)) -+ return FALSE; -+ -+ if (!sd_check_err(status)) -+ return FALSE; -+ -+ return TRUE; -+} -+ -+int sd_set_card_standby(sd_card_t *info) -+{ -+ uint state; -+ int count = 0; -+ while (count++ < SD_CARD_STATE_CHANGE_RETRY_COUNT) { -+ if (!sd_get_card_state(info, &state)) -+ return FALSE; -+ -+ switch (state) { -+ case SD_IDLE_STATE: -+ case SD_READY_STATE: -+ case SD_IDENT_STATE: -+ printk("%s() error\n", __func__); -+ return FALSE; -+ case SD_DIS_STATE: -+ return sd_operation_complete(info, SD_STBY_STATE); -+ case SD_TRAN_STATE: -+ if (!sdc_send_cmd(SD_SELECT_CARD_CMD, 0, NULL)) -+ return FALSE; -+ break; -+ case SD_DATA_STATE: -+ if (sd_operation_complete(info, SD_TRAN_STATE)) -+ return TRUE; -+ if (sd_err_code != ERR_NO_ERROR) -+ return FALSE; -+ if (!sd_stop_transmission()) -+ return FALSE; -+ break; -+ case SD_RCV_STATE: -+ if (sd_operation_complete(info, SD_TRAN_STATE)) -+ return TRUE; -+ if (sd_err_code != ERR_NO_ERROR) -+ return FALSE; -+ if (!sd_stop_transmission()) -+ return FALSE; -+ break; -+ case SD_PRG_STATE: -+ if (!sd_operation_complete(info, SD_TRAN_STATE)) -+ return FALSE; -+ break; -+ case SD_STBY_STATE: -+ return TRUE; -+ } -+ } -+ P_DEBUG("%s() error\n", __func__); -+ return FALSE; -+} -+ -+uint two_power(uint n) -+{ -+ uint pow = 1; -+ -+ for (; n > 0; n--) -+ pow <<= 1; -+ return pow; -+} -+ -+int sd_csd_parse(sd_csd_t *csd, uint *csd_word) -+{ -+ sd_csd_bit_t *csd_bit; -+ uint mult, blocks, len; -+ -+ if ((csd_word[0] & 0x00000001) != 1) { -+ sd_err_code = ERR_CSD_REGISTER_ERROR; -+ printk("%s() ERR_CSD_REGISTER_ERROR\n", __func__); -+ return FALSE; -+ } -+ -+ csd_bit = (sd_csd_bit_t *) csd_word; -+ csd->CSDStructure = csd_bit->CSD_STRUCTURE; -+ csd->MMCSpecVersion = csd_bit->MMC_SPEC_VERS; -+ csd->TAAC_u = TAAC_TimeValueTable_u[csd_bit->TAAC_TimeValue] * TAAC_TimeUnitTable[csd_bit->TAAC_TimeUnit] / 10; -+ csd->NSAC_u = csd_bit->NSAC * 100; -+ csd->TransferSpeed = TRANS_SPEED_RateUintTable[csd_bit->TRAN_SPEED_RateUnit] * TRANS_SPEED_TimeValueTable_u[csd_bit->TRAN_SPEED_TimeValue] / 10; -+ csd->CardCmdClass = csd_bit->CCC; -+ csd->ReadBlockLength = two_power(csd_bit->READ_BL_LEN); -+ csd->ReadBlockPartial = csd_bit->READ_BL_PARTIAL; -+ csd->WriteBlockMisalign = csd_bit->WRITE_BLK_MISALIGN; -+ csd->ReadBlockMisalign = csd_bit->READ_BLK_MISALIGN; -+ csd->DSRImplemant = csd_bit->DSR_IMP; -+ mult = 1 << (csd_bit->C_SIZE_MULT + 2); -+ blocks = ((csd_bit->C_SIZE_1 | (csd_bit->C_SIZE_2 << 2)) + 1) * mult; -+ len = 1 << (csd_bit->READ_BL_LEN); -+ csd->BlockNumber = blocks; -+ csd->MemorySize = blocks * len; -+ csd->VDDReadMin_u = VDD_CURR_MIN_Table_u[csd_bit->VDD_R_CURR_MIN]; -+ csd->VDDReadMax_u = VDD_CURR_MAX_Table_u[csd_bit->VDD_R_CURR_MAX]; -+ csd->VDDWriteMin_u = VDD_CURR_MIN_Table_u[csd_bit->VDD_W_CURR_MIN]; -+ csd->VDDWriteMax_u = VDD_CURR_MAX_Table_u[csd_bit->VDD_W_CURR_MAX]; -+ csd->EraseBlkEnable = csd_bit->ERASE_BLK_ENABLE; -+ csd->EraseSectorSize = csd_bit->ERASE_SECTOR_SIZE + 1; -+ csd->WriteProtectGroupSize = csd_bit->WP_GRP_SIZE + 1; -+ csd->WriteProtectGroupEnable = csd_bit->WP_GRP_ENABLE; -+ csd->WriteSpeedFactor = two_power(csd_bit->R2W_FACTOR); -+ csd->WriteBlockLength = two_power(csd_bit->WRITE_BL_LEN); -+ csd->WriteBlockPartial = csd_bit->WRITE_BL_PARTIAL; -+ csd->CopyFlag = csd_bit->COPY; -+ csd->PermanentWriteProtect = csd_bit->PERM_WRITE_PROTECT; -+ csd->TemporaryWriteProtect = csd_bit->TMP_WRITE_PROTECT; -+ -+ if (csd_bit->FILE_FORMAT_GRP == 0) -+ csd->FileFormat = csd_bit->FILE_FORMAT; -+ else -+ csd->FileFormat = FILE_FORMAT_RESERVED; -+ -+ return TRUE; -+} -+ -+int sd_cid_parse(sd_cid_t *cid, uint *cid_word) -+{ -+ unchar *ptr; -+ int i; -+ -+ if ((cid_word[0] & 0x00000001) != 1) -+ { -+ sd_err_code = ERR_CID_REGISTER_ERROR; -+ printk("%s() ERR_CID_REGISTER_ERROR\n", __func__); -+ return FALSE; -+ } -+ -+ cid->ManufacturerID = (cid_word[3] & 0xFF000000) >> 24; -+ cid->ApplicationID = (cid_word[3] & 0x00FFFF00) >> 8; -+ -+ ptr = (unchar *) cid_word; -+ ptr += 15 - 3; -+ for (i = 0; i < 6; i++, ptr--) -+ cid->ProductName[i] = *ptr; -+ cid->ProductName[6] = '\0' ; -+ -+ cid->ProductRevisionLow = (cid_word[1] & 0x00F00000) >> 20; -+ cid->ProductRevisionHigh = (cid_word[1] & 0x000F0000) >> 16; -+ cid->ProductSerialNumber = ((cid_word[1] & 0x0000FFFF) << 16) + ((cid_word[0] & 0xFFFF0000) >> 16); -+ cid->ManufactureMonth = ((cid_word[0] & 0x00000F00) >> 8); -+ cid->ManufactureYear = ((cid_word[0] & 0x0000F000) >> 12) + SD_DEFAULT_YEAR_CODE; -+ -+ return TRUE; -+} -+ -+uint sd_read_timeout_cycle(uint clock, sd_csd_t *csd) -+{ -+#if 1 //ivan for 100ms maximux from document "ProdManualIndGradeSDv1.0[1].pdf" chapter A-2 -+ return clock/10; // /10; -+#else -+ uint ret, total, per; -+ -+ per = 1000000000 / clock; -+ total = (csd->TAAC_u + (csd->NSAC_u * 100 * per)) * 100; -+ -+ if (total > (100 * 1000 * 1000)) -+ total = 100 * 1000 * 1000; -+ ret = total / per; -+ -+ return ret; -+#endif -+} -+ -+uint sd_block_size_convert(uint size) -+{ -+ uint ret = 0; -+ -+ while (size >= 2) { -+ size >>= 1; -+ ret++; -+ } -+ return ret; -+} -+ -+int sd_select_card(sd_card_t *info) -+{ -+ uint status; -+ -+ /* send CMD7 with valid RCA to select */ -+ if (!sdc_send_cmd(SD_SELECT_CARD_CMD | SDC_CMD_REG_NEED_RSP, ((uint)info->RCA) << 16, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ return TRUE; -+} -+ -+int sd_set_transfer_state(sd_card_t *info) -+{ -+ uint state; -+ int count = 0; -+ while (count++ < SD_CARD_STATE_CHANGE_RETRY_COUNT) { -+ if (!sd_get_card_state(info, &state)) -+ return FALSE; -+ -+ switch (state) { -+ case SD_IDLE_STATE: -+ case SD_READY_STATE: -+ case SD_IDENT_STATE: -+ printk("%s() error\n", __func__); -+ return FALSE; -+ case SD_DIS_STATE: -+ if (!sd_operation_complete(info, SD_STBY_STATE)) -+ return FALSE; -+ break; -+ case SD_TRAN_STATE: -+ return TRUE; -+ case SD_DATA_STATE: -+ if (sd_operation_complete(info, SD_TRAN_STATE)) -+ return TRUE; -+ if (sd_err_code != ERR_NO_ERROR) -+ return FALSE; -+ if (!sd_stop_transmission()) -+ return FALSE; -+ break; -+ case SD_RCV_STATE: -+ if (sd_operation_complete(info, SD_TRAN_STATE)) -+ return TRUE; -+ if (sd_err_code != ERR_NO_ERROR) -+ return FALSE; -+ if (!sd_stop_transmission()) -+ return FALSE; -+ break; -+ case SD_PRG_STATE: -+ if (!sd_operation_complete(info, SD_TRAN_STATE)) -+ return FALSE; -+ break; -+ case SD_STBY_STATE: -+ if (!sd_select_card(info)) -+ return FALSE; -+ } -+ } -+ P_DEBUG("%s() error\n", __func__); -+ return FALSE; -+} -+ -+uint sd_write_timeout_cycle(uint clock, sd_csd_t *CSD) -+{ -+#if 1 //ivan for 250ms maximux from document -+ return clock/4; //ijsung hack -+#else -+ uint ret, total, pre; -+ -+ pre = 1000000000 / clock; -+ total = CSD->WriteSpeedFactor * 100 * (CSD->TAAC_u + (CSD->NSAC_u * 100 * pre)); -+ -+ if (total > (100 * 1000 * 1000)) -+ total = 100 * 1000 * 1000; -+ ret = total / pre; -+ -+ return ret; -+#endif -+} -+ -+int sd_card_identify(sd_card_t *info) -+{ -+ uint rca, status, cid[4]; -+ -+ /* reset all cards */ -+ if (!sdc_send_cmd(SD_GO_IDLE_STATE_CMD, 0, NULL)) -+ return FALSE; -+ udelay(1000); -+ /* Do operating voltage range validation */ -+ /* get OCR register */ -+ if (!sd_get_ocr(info, SDC_OCR, (uint *) &info->OCR)) -+ return FALSE; -+ /* ckeck the operation conditions */ -+ if ((info->OCR & SDC_OCR) == 0) { -+ sd_err_code = ERR_OUT_OF_VOLF_RANGE; -+ return FALSE; -+ } -+ -+ /* send CMD2 to get CID register */ -+ if (!sdc_send_cmd(SD_ALL_SEND_CID_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, 0, cid)) -+ return FALSE; -+ if (info->CardType == MEMORY_CARD_TYPE_SD) { -+ /* send CMD3 to get RCA register */ -+ if (!sdc_send_cmd(SD_SEND_RELATIVE_ADDR_CMD | SDC_CMD_REG_NEED_RSP, 0, &rca)) -+ return FALSE; -+ info->RCA = (ushort) (rca >> 16); -+ } else { -+ /* so far, we only support one interface, so we can give RCA any value */ -+ info->RCA = 0x1; -+ /* send CMD3 to set RCA register */ -+ if (!sdc_send_cmd(SD_SEND_RELATIVE_ADDR_CMD | SDC_CMD_REG_NEED_RSP, (info->RCA << 16), &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+int sd_card_init(sd_card_t *info) -+{ -+ uint clock; -+ -+ P_DEBUG("--> %s\n", __func__); -+ if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) -+ return FALSE; -+ sd_err_code = ERR_NO_ERROR; -+ /* At first, set card type to SD */ -+ info->CardType = MEMORY_CARD_TYPE_SD; -+ /* set memory card type */ -+ sdc_set_card_type(info->CardType); -+ /* start card idenfication process */ -+ if (!sd_card_identify(info)) { -+ printk("this is not SD card\n"); -+ sd_err_code = ERR_NO_ERROR; -+ info->CardType = MEMORY_CARD_TYPE_MMC; -+ /* set memory card type */ -+ sdc_set_card_type(info->CardType); -+ if (!sd_card_identify(info)) -+ return FALSE; -+ } -+ -+ /* get CSD */ -+ if (!sd_set_card_standby(info)) -+ return FALSE; -+ /* send CMD9 to get CSD register */ -+ if (!sdc_send_cmd(SD_SEND_CSD_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, ((uint) info->RCA) << 16, info->CSDWord)) -+ return FALSE; -+ sd_csd_parse(&info->CSD, info->CSDWord); -+ -+ if (info->CSD.ReadBlockLength != SD_SECTOR_SIZE) { -+ printk("Sector size is mis-matched (SD CSD report=0x%X,SD_SECTOR_SIZE=0x%X)\n", info->CSD.ReadBlockLength, SD_SECTOR_SIZE); -+ info->CSD.ReadBlockLength = SD_SECTOR_SIZE; -+// return FALSE; -+ } -+ -+ /* get CID */ -+ /* send CMD10 to get CID register */ -+ if (!sdc_send_cmd(SD_SEND_CID_CMD | SDC_CMD_REG_NEED_RSP | SDC_CMD_REG_LONG_RSP, ((uint) info->RCA) << 16, info->CIDWord)) -+ return FALSE; -+ sd_cid_parse(&info->CID, info->CIDWord); -+ -+ /* Set card bus clock. sdc_set_bus_clock() will give the real card bus clock has been set. */ -+ clock = sdc_set_bus_clock(info, info->CSD.TransferSpeed); -+ info->ReadAccessTimoutCycle = sd_read_timeout_cycle(clock, &(info->CSD)); -+ info->WriteAccessTimoutCycle = sd_write_timeout_cycle(clock, &(info->CSD)); -+ /* set bus width */ -+ if (!sdc_set_bus_width(info)) -+ return FALSE; -+ -+ /* check write protect */ -+ info->WriteProtect = ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_LOCK) == SDC_STATUS_REG_CARD_LOCK) ? TRUE : FALSE; -+ if(info->WriteProtect == TRUE) -+ printk("SD/MMC Card is Write Protected\n"); -+ info->ActiveState = TRUE; -+ P_DEBUG("<-- %s\n", __func__); -+ -+ return TRUE; -+} -+ -+int sd_card_insert(sd_card_t *info) -+{ -+ P_DEBUG("--> %s\n", __func__); -+ /* reset host interface controller */ -+ sdc_reset(); -+ /* turn on clock using default clock*/ -+ SDC_W_REG(SDC_CLOCK_CTRL_REG, SDC_R_REG(SDC_CLOCK_CTRL_REG)&0xff); -+ -+ if (!sd_card_init(info)) { -+ printk("root initialize failed\n"); -+ return FALSE; -+ } -+ /* set interrupt mask register */ -+ SDC_W_REG(SDC_INT_MASK_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); -+ P_DEBUG("<-- %s\n", __func__); -+ -+ return TRUE; -+} -+ -+int sd_card_remove(sd_card_t *info) -+{ -+ sd_err_code = ERR_NO_ERROR; -+ -+ info->ActiveState = FALSE; -+ info->WriteProtect = FALSE; -+ info->RCA = 0; -+ /* reset host interface controller */ -+ sdc_reset(); -+ /* set interrupt mask register */ -+ SDC_W_REG(SDC_INT_MASK_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); -+ sd_err_code = ERR_CARD_NOT_EXIST; -+ /* turn off clock */ -+ SDC_W_REG(SDC_CLOCK_CTRL_REG, SDC_R_REG(SDC_CLOCK_CTRL_REG) | 0x100); -+ return TRUE; -+} -+ -+irqreturn_t sd_hotswap_interrupt_handler(int irq, void *dev_id) -+{ -+ uint status; -+ struct sd_dev *dev = dev_id; -+ -+ P_DEBUG("--> %s, irq=%d\n", __func__, irq); -+ /* When the card is inserted or removed, we must delay a short time to make sure */ -+ /* the SDC_STATUS_REG_CARD_INSERT bit of status register is stable */ -+ udelay(1000); -+ status = SDC_R_REG(SDC_STATUS_REG); -+ if ((status & SDC_STATUS_REG_CARD_CHANGE) == SDC_STATUS_REG_CARD_CHANGE) { -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); -+ if ((status & SDC_STATUS_REG_CARD_INSERT) == SDC_CARD_INSERT) { -+ dev->card_state = SD_CARD_INSERT; -+ printk("Card Insert\n"); -+ sd_card_insert(&sd_card_info); -+ } else { -+ dev->card_state = SD_CARD_REMOVE; -+ printk("Card Remove\n"); -+ sd_card_remove(&sd_card_info); -+ /* remove all current transfers as I/O error*/ -+#if 0 //ASYNC -+ spin_lock_irqsave(&io_request_lock, status); -+ INIT_REQUEST; -+ while(!QUEUE_EMPTY) -+ end_request(0); -+ bh_busy=0; -+ spin_unlock_irqrestore(&io_request_lock, status); -+#endif -+ } -+ } else if ((status & SDC_STATUS_REG_DATA_TIMEOUT) == SDC_STATUS_REG_DATA_TIMEOUT) { -+ SDC_W_REG(SDC_CLEAR_REG, SDC_STATUS_REG_CARD_CHANGE | SDC_STATUS_REG_DATA_TIMEOUT); -+ -+#if 0 //ASYNC -+ printk("Data timeout. Retry.\n"); -+ sd_clustered_bh(2); -+#else -+ printk("Data timeout. Retry.\n"); -+#endif -+ } -+ P_DEBUGG("card state=%d\n", dev->card_state); -+ P_DEBUG("<-- %s\n", __func__); -+ return IRQ_HANDLED; -+} -+ -+/*------------------------------------ -+ * Block-driver specific functions -+ */ -+/* -+ * Find the device for this request. -+ */ -+#if 0 -+static inline struct sd_dev *sd_locate_device(const struct request *req) -+{ -+ int devno; -+ struct sd_dev *dev; -+ -+ P_DEBUG("--> %s\n", __func__); -+#if 0 -+ /* Check if the minor number is in range */ -+ devno = DEVICE_NR(req->rq_dev); -+ P_DEBUGG("minor=%d\n", devno); -+ if (devno >= SD_DEVS) { -+ static int count = 0; -+ -+ if (count++ < 5) /* print the message at most five times */ -+ P_DEBUG("request for unknown device\n"); -+ return NULL; -+ } -+#endif -+ dev = sd_devices + devno; -+ P_DEBUGG("card_state=%d\n", dev->card_state); -+ P_DEBUG("<-- %s\n", __func__); -+ return dev; -+} -+ -+int sd_card_check_exist(sd_card_t *info) -+{ -+ /* if card is not exist */ -+ if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) { -+ sd_card_remove(info); -+ return FALSE; -+ } -+ /* if card is not active */ -+ if (!info->ActiveState) -+ { -+ return sd_card_insert(info); -+ } -+ return TRUE; -+} -+#endif -+ -+void sd_reset_host_controller(void) -+{ -+ uint clock, mask, width; -+ -+ /* read register */ -+ clock = SDC_R_REG(SDC_CLOCK_CTRL_REG); -+ width = SDC_R_REG(SDC_BUS_WIDTH_REG); -+ mask = SDC_R_REG(SDC_INT_MASK_REG); -+ /* reset host interface */ -+ sdc_reset(); -+ /* restore register */ -+ SDC_W_REG(SDC_CLOCK_CTRL_REG, clock); -+ SDC_W_REG(SDC_BUS_WIDTH_REG, width); -+ SDC_W_REG(SDC_INT_MASK_REG, mask); -+} -+ -+int sd_read_single_block(sd_card_t *info, uint addr, uint size, uint timeout, unchar *buf) -+{ -+ uint status; -+ -+ if (!sdc_set_block_size(size)) -+ return FALSE; -+ -+ sdc_config_transfer(info, size, size, SDC_DATA_CTRL_REG_DATA_READ, timeout); -+ -+ if (!sdc_send_cmd(SD_READ_SINGLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ -+#ifdef DELAY_FOR_DMA_READ -+ if (first_run==0) { -+ int i=0; -+ for(i=0;i<10;i++) -+ udelay(1000); -+ first_run=1; -+ } -+#endif -+ if (!sdc_read_block(info, size, (uint *) buf)) -+ return FALSE; -+ -+ if (sd_err_code != ERR_NO_ERROR) { -+ printk("%s() error=0x%X\n", __func__, sd_err_code); -+ sd_reset_host_controller(); -+ return FALSE; -+ } else { -+ if (!sdc_check_data_end()) { -+ sd_stop_transmission(); -+ printk("%s()2 error=0x%X\n", __func__, sd_err_code); -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+int sd_write_single_block(sd_card_t *info, uint addr, uint size, uint timeout, unchar *buf) -+{ -+ uint status; -+ -+ if (!sdc_set_block_size(size)) -+ return FALSE; -+ -+ sdc_config_transfer(info, size, size, SDC_DATA_CTRL_REG_DATA_WRITE, timeout); -+ -+ if (!sdc_send_cmd(SD_WRITE_SINGLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ -+ if (!sdc_write_block(info, size, (uint *) buf)) -+ return FALSE; -+ if (sd_err_code != ERR_NO_ERROR) { -+ printk("%s() error=0x%X\n", __func__, sd_err_code); -+ sd_reset_host_controller(); -+ return FALSE; -+ } else { -+ if (!sdc_check_data_end()) { -+ sd_stop_transmission(); -+ printk("%s()2 error=0x%X\n", __func__, sd_err_code); -+ return FALSE; -+ } -+ } -+ -+ return TRUE; -+} -+ -+int sd_read_multiple_block(sd_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) -+{ -+ uint err, status; -+ -+ if (!sdc_set_block_size(size)) -+ return FALSE; -+ -+ sdc_config_transfer(info, count * size, size, SDC_DATA_CTRL_REG_DATA_READ, timeout); -+ -+ if (!sdc_send_cmd(SD_READ_MULTIPLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+ -+#ifdef DELAY_FOR_DMA_READ -+ if (first_run==0) { -+ int i=0; -+ for(i=0;i<10;i++) -+ udelay(1000); -+ first_run=1; -+ } -+#endif -+#if 0 //ijsung: Sometimes this will cause IRQ lost, and is slower. Use method below -+ while (count > 0) { -+ if (!sdc_read_block(info, size, (uint *) buf)) -+ return FALSE; -+ count--; -+ buf += size; -+ } -+#else //ijsung: DMA at once. -+ if (!sdc_read_block(info, size*count, (uint *) buf)) -+ return FALSE; -+#endif -+ if (sd_err_code != ERR_NO_ERROR) { -+ err = sd_err_code; -+ sd_stop_transmission(); -+ sd_reset_host_controller(); -+ sd_err_code |= err; -+ printk("%s() error=0x%X\n", __func__, sd_err_code); -+ return FALSE; -+ } else { -+ if (!sdc_check_data_end()) { -+ err = sd_err_code; -+ sd_stop_transmission(); -+ sd_err_code |= err; -+ printk("%s()2 error=0x%X\n", __func__, sd_err_code); -+ return FALSE; -+ } -+ if (!sd_stop_transmission()) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+int sd_write_multiple_block(sd_card_t *info, uint addr, uint count, uint size, uint timeout, unchar *buf) -+{ -+ uint ErrorCode, status; -+ -+ if(!sdc_set_block_size(size)) -+ return FALSE; -+ -+ sdc_config_transfer(info, count * size, size, SDC_DATA_CTRL_REG_DATA_WRITE, timeout); -+ sdc_pre_erase_cmd(count); //ijsung: pre-erase -+ if (!sdc_send_cmd(SD_WRITE_MULTIPLE_BLOCK_CMD | SDC_CMD_REG_NEED_RSP, addr, &status)) -+ return FALSE; -+ if (!sd_check_err(status)) -+ return FALSE; -+#if 0 //ijsung: Sometimes this will cause IRQ lost, and is slower. Use method below -+ while (count > 0) { -+ if (!sdc_write_block(info, size, (uint *) buf)) -+ return FALSE; -+ count--; -+ buf += size; -+ } -+#else //ijsung: DMA at once. -+ if (!sdc_write_block(info, size*count, (uint *) buf)) -+ return FALSE; -+#endif -+ -+ if (sd_err_code != ERR_NO_ERROR) -+ { -+ ErrorCode = sd_err_code; -+ sd_stop_transmission(); -+ sd_reset_host_controller(); -+ sd_err_code |= ErrorCode; -+ printk("%s() error=0x%X\n", __func__, sd_err_code); -+ return FALSE; -+ } else { -+ if (!sdc_check_data_end()) { -+ ErrorCode = sd_err_code; -+ sd_stop_transmission(); -+ sd_err_code |= ErrorCode; -+ printk("%s()2 error=0x%X\n", __func__, sd_err_code); -+ return FALSE; -+ } -+ if (!sd_stop_transmission()) -+ return FALSE; -+ } -+ -+ return TRUE; -+} -+ -+int sd_wait_transfer_state(sd_card_t *info) -+{ -+ uint state; -+ int count = 0; -+ while (count++ < SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT) { -+ if (!sd_get_card_state(info, &state)) -+ return FALSE; -+ -+ switch (state) { -+ case SD_IDLE_STATE: -+ case SD_READY_STATE: -+ case SD_IDENT_STATE: -+ case SD_DIS_STATE: -+ case SD_STBY_STATE: -+ printk("%s() error\n", __func__); -+ return FALSE; -+ case SD_TRAN_STATE: -+ return TRUE; -+ case SD_DATA_STATE: -+ case SD_RCV_STATE: -+ case SD_PRG_STATE: -+ break; -+ } -+ } -+ sd_err_code = ERR_SD_CARD_IS_BUSY; -+ P_DEBUG("%s() ERR_SD_CARD_IS_BUSY\n", __func__); -+ return FALSE; -+} -+ -+/*************************************************************************** -+SD Card Read/Write/Erase Function -+***************************************************************************/ -+int sd_read_sector(sd_card_t *info, uint addr, uint count, unchar *buf) -+{ -+ int cnt; -+ uint start; -+ sync_mode=1; -+ P_DEBUG("%s : sector = %d,count = %d\n",__func__,addr,count); -+ if (count > MAX_READ_SECTOR_NR) { -+ P_DEBUG("Readable Block Number Per Commands is 0x%X\n",MAX_READ_SECTOR_NR); -+ return FALSE; -+ } -+ -+ sd_err_code = ERR_NO_ERROR; -+ -+ if (!info->ActiveState) { -+ P_DEBUG("%s : SD card not active!!\n", __func__); -+ return FALSE; -+ } -+ -+ if (!sd_set_transfer_state(info)) -+ return FALSE; -+ -+ start = addr * info->CSD.ReadBlockLength; -+ cnt = (int) count; -+ -+ while (cnt > 0) { -+ if (cnt > 1) { -+ if (!sd_read_multiple_block(info, start, (cnt > MAX_MULTI_BLOCK_NUM) ? MAX_MULTI_BLOCK_NUM : cnt, -+ info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)) -+ return FALSE; -+ } else { -+ if (!sd_read_single_block(info, start, info->CSD.ReadBlockLength, info->ReadAccessTimoutCycle, buf)) -+ return FALSE; -+ return TRUE; -+ } -+ -+ if (!sd_wait_transfer_state(info)) -+ return FALSE; -+ -+ cnt -= MAX_MULTI_BLOCK_NUM; -+ start += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; -+ buf += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; -+ } -+ -+ return TRUE; -+} -+ -+int sd_write_sector(sd_card_t *info, uint addr, uint count, unchar *buf) -+{ -+ int cnt; -+ uint start; -+ -+ if (count > MAX_WRITE_SECTOR_NR) { -+ P_DEBUG("Writable Block Number Per Commands is 0x%X\n",MAX_WRITE_SECTOR_NR); -+ return FALSE; -+ } -+ -+ sd_err_code = ERR_NO_ERROR; -+ -+ if (!info->ActiveState) { -+ P_DEBUG("%s : SD card not active!!\n", __func__); -+ return FALSE; -+ } -+ -+ if (info->WriteProtect == TRUE) { -+ sd_err_code = ERR_SD_CARD_IS_LOCK; -+ printk("Write Protected!!\n"); -+ return FALSE; -+ } -+ if (!sd_set_transfer_state(info)) -+ return FALSE; -+ -+ start = addr * info->CSD.ReadBlockLength; -+ cnt = (int) count; -+ -+ while (cnt > 0) { -+ if (cnt > 1) { -+ if (!sd_write_multiple_block(info, start, (cnt > MAX_MULTI_BLOCK_NUM) ? MAX_MULTI_BLOCK_NUM : cnt, -+ info->CSD.ReadBlockLength, info->WriteAccessTimoutCycle, buf)) -+ return FALSE; -+ } else { -+ if (!sd_write_single_block(info, start, info->CSD.ReadBlockLength, info->WriteAccessTimoutCycle, buf)) -+ return FALSE; -+ return TRUE; -+ } -+ -+ if (!sd_wait_transfer_state(info)) -+ return FALSE; -+ -+ cnt -= MAX_MULTI_BLOCK_NUM; -+ start += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; -+ buf += MAX_MULTI_BLOCK_NUM * info->CSD.ReadBlockLength; -+ } -+ -+ return TRUE; -+} -+/*---------------------------------------------- -+ * Perform an actual transfer: -+ * Returns: # of sectors transferred. 0 = error -+ */ -+static int sd_transfer(struct sd_dev *device, const struct request *req) -+{ -+ int status = 0; -+ int count = 0; -+ -+ struct bio *bio = req->bio; -+ struct bio_vec *bvec; -+ struct req_iterator iter; -+ -+ spin_unlock_irq( &device->lock); -+ -+#if 0 -+ P_DEBUG("\nreq sector: %d, nr_sectors: %d, hard_cur_sectors: %d phys_seg: %d, buf: 0x%08lx\n", -+ (int)req->sector, (int)req->nr_sectors, (int)req->hard_cur_sectors, -+ (int)req->nr_phys_segments, (ulong)bio_data( bio)); -+#endif -+ -+ rq_for_each_segment( bvec, req, iter) { -+ -+ unsigned char *buf = page_address( bvec->bv_page) + bvec->bv_offset; -+ int sectors = bio_cur_bytes(bio) >> 9; -+ -+ P_DEBUG("bvec[%2d]: sector: %d, count: %d, curr: %d, buf: 0x%08lx, ", -+ iter.i, (int)bio->bi_sector, count, (int)sectors, (unsigned long)buf); -+ -+ sd_card_info.private = (void *)&device->ch_req; -+ -+ if( rq_data_dir(req) == 0) /* Read */ -+ status = sd_read_sector( &sd_card_info, sector_offset + bio->bi_sector, sectors, buf); -+ else -+ status = sd_write_sector( &sd_card_info, sector_offset + bio->bi_sector, sectors, buf); -+ -+ P_DEBUG("status: %d\n", status); -+ -+ if (status <= 0) { -+ spin_lock_irq( &device->lock); -+ return count; -+ } -+ -+ count += sectors; -+ bio->bi_sector += sectors; -+ } -+ -+ if( ( req->__sector == 0) && !Do_onetime){ -+ -+ unsigned char *buf = bio_data( bio); -+ -+ if( ( buf[ 0x1be] != 0x0) && ( buf[ 0x1be] != 0x80)) /* partition identify */ -+ sector_offset = 0; //sector 0 is PBR -+ else -+ sector_offset = ( buf[ 0x1c6]) | ( buf[ 0x1c7] << 8) | ( buf[ 0x1c8] <<16) |( buf[ 0x1c9] << 24); -+ -+ P_DEBUG( "sector_offset = %d\n", sector_offset); -+ Do_onetime = 1; -+ } -+ -+ spin_lock_irq( &device->lock); -+ -+ if( status <= 0) -+ return 0; -+ else -+ return count; -+} -+ -+#ifdef SD_DEBUG -+uint sd_dev_info(void) -+{ -+ sd_csd_t *CSD; -+ sd_cid_t *CID; -+ -+ P_DEBUG("============SDCard=====================================\n"); -+#if 0 -+ if (!sd_card_check_exist(&sd_card_info)) -+ { -+ P_DEBUG("SD Card does not exist!!!"); -+ return FALSE; -+ } -+#else -+ if (!sd_card_info.ActiveState) { -+ P_DEBUG("%s : SD card not active!!\n", __func__); -+ return FALSE; -+ } -+#endif -+ -+ /* print OCR, RCA register */ -+ P_DEBUG("OCR>> 0x%08X RCA>> 0x%04X\n", (uint) sd_card_info.OCR, sd_card_info.RCA); -+ /* print CID register */ -+ P_DEBUG("CID>> 0x%08X 0x%08X 0x%08X 0x%08X\n", sd_card_info.CIDWord[0], sd_card_info.CIDWord[1], sd_card_info.CIDWord[2], sd_card_info.CIDWord[3]); -+ CID = &(sd_card_info.CID); -+ P_DEBUG(" MID:0x%02X OID:0x%04X PNM:%s PRV:%d.%d PSN:0x%08X\n", CID->ManufacturerID, CID->ApplicationID, CID->ProductName, -+ CID->ProductRevisionHigh, CID->ProductRevisionLow, CID->ProductSerialNumber); -+ P_DEBUG(" MDT:%d/%d\n", CID->ManufactureMonth, CID->ManufactureYear); -+ /* print CSD register */ -+ P_DEBUG("CSD>> 0x%08X 0x%08X 0x%08X 0x%08X\n", sd_card_info.CSDWord[0], sd_card_info.CSDWord[1], sd_card_info.CSDWord[2], sd_card_info.CSDWord[3]); -+ CSD = &(sd_card_info.CSD); -+ P_DEBUG(" CSDStructure:%d Spec.Version:%d\n", CSD->CSDStructure, CSD->MMCSpecVersion); -+ P_DEBUG(" TAAC:%dns NSAC:%d clock cycles\n", CSD->TAAC_u, CSD->NSAC_u); -+ P_DEBUG(" TransferSpeed:%d bit/s CardCommandClass:0x%03X\n", CSD->TransferSpeed, CSD->CardCmdClass); -+ P_DEBUG(" ReadBlLen:%d ReadBlPartial:%X WriteBlkMisalign:%X ReadBlkMisalign:%X\n", CSD->ReadBlockLength, CSD->ReadBlockPartial, CSD->WriteBlockMisalign, CSD->ReadBlockMisalign); -+ P_DEBUG(" DSP:%X BlockNumber:%d MemorySize:%d \n", CSD->DSRImplemant, CSD->BlockNumber, CSD->MemorySize); -+ P_DEBUG(" VDD_R_MIN:%d/10mA VDD_R_MAX:%dmA\n", (uint) CSD->VDDReadMin_u, (uint) CSD->VDDReadMax_u); -+ P_DEBUG(" VDD_W_MIN:%d/10mA VDD_W_MAX:%dmA\n", (uint) CSD->VDDWriteMin_u, (uint) CSD->VDDWriteMax_u); -+ P_DEBUG(" EraseBlkEnable:%d EraseSectorSize:%d WpGrpSize:%d WpGrpEnable:%X\n", CSD->EraseBlkEnable, CSD->EraseSectorSize, CSD->WriteProtectGroupSize, CSD->WriteProtectGroupEnable); -+ P_DEBUG(" WriteSpeedFactor:%d WriteBlLen:%d WriteBlPartial:%X\n", CSD->WriteSpeedFactor, CSD->WriteBlockLength, CSD->WriteBlockPartial); -+ P_DEBUG(" Copy:%X PermWrProtect:%X TmpWrProtect:%X FileFormat:%X\n", CSD->CopyFlag, CSD->PermanentWriteProtect, CSD->TemporaryWriteProtect, CSD->FileFormat); -+ P_DEBUG(" ReadTimoutCycle:0x%08X WriteTimoutCycle:0x%08X\n", sd_card_info.ReadAccessTimoutCycle, sd_card_info.WriteAccessTimoutCycle); -+ /* print SCR register */ -+ P_DEBUG("SCR>> 0x%08X 0x%08X \n", *(((uint *) &sd_card_info.SCR)), *(((uint *) &sd_card_info.SCR) + 1)); -+ P_DEBUG(" SCR_STRUCTURE:%d, SD_SPEC:%d, Data_status_after_erase:%d\n", sd_card_info.SCR.SCR_STRUCTURE, sd_card_info.SCR.SD_SPEC, sd_card_info.SCR.DATA_STAT_AFTER_ERASE); -+ P_DEBUG(" sd_security:%d, SD_BUS_WIDTH:%X\n", sd_card_info.SCR.SD_SECURITY, sd_card_info.SCR.SD_BUS_WIDTH); -+ -+ return TRUE; -+} -+#endif -+ -+static int sd_card_setup(struct sd_dev *dev) -+{ -+ uint sd_card_size; -+ int i; -+ -+ P_DEBUG("--> %s\n", __func__); -+ first_run = 0; -+ sd_err_code = ERR_NO_ERROR; -+ -+ sd_card_info.ActiveState = FALSE; -+ sd_card_info.WriteProtect = FALSE; -+ sd_card_info.IOAddr = FTSDC_VA_BASE; -+ sd_card_info.DMAEnable = FALSE; -+ -+ sd_card_info.SysFrequency = AHB_CLK_IN/2; -+ P_DEBUG("DMA Enable is %d, Sys frequency = %d\n", sd_card_info.DMAEnable, sd_card_info.SysFrequency); -+ sd_card_info.RCA = 0; -+ sd_card_info.Drive = 'S'; -+ -+ if (!sd_card_insert(&sd_card_info)) -+ return FALSE; -+#ifdef SD_DEBUG -+ if (!sd_dev_info()) -+ return FALSE; -+#endif -+ sd_card_size = sd_card_info.CSD.MemorySize; -+ printk(KERN_NOTICE "FTSDC010: SD Card Capacity=%d MB\n", sd_card_size/1000000); /* Marketing MB is not 1048576 */ -+ -+ for (i = 0; i < SD_DEVS; i++) { -+ sd_devices[i].size = sd_card_size / SD_SECTOR_SIZE; //unit is block, not bytes -+ -+#if 0 -+ sd_partitions[i << SD_SHIFT].nr_sects =sd_size * (SD_BLKSIZE / SD_SECTOR_SIZE); -+ P_DEBUG ("%s() %d-th device, size=%d blks(blks=%d),nr_sects=%ld\n", __func__, i, sd_size, SD_BLKSIZE, sd_partitions[i << SD_SHIFT].nr_sects); -+#endif -+ //sd_devices[i].card_state = SD_CARD_WORK; -+ //sema_init(&(sd_devices[i].sema), 1); // add by Charles Tsai*/ -+ } -+ -+ sd_card_info.DMAEnable = dev->dma_enable; -+ -+ P_DEBUG("<-- %s\n", __func__); -+ return TRUE; -+} -+ -+/* -+ * Driver stuff -+ */ -+/*------------------------------------ -+ * The ioctl implementation -+ */ -+int sd_ioctl(struct block_device *bdev, fmode_t mode, unsigned int cmd, unsigned long arg) -+{ -+ int size; -+ struct hd_geometry geo; -+ struct sd_dev *device=bdev->bd_disk->private_data; -+ P_DEBUG ("ioctl 0x%x 0x%lx\n", cmd, arg); -+ switch (cmd) { -+ case BLKGETSIZE: -+ /* Return the device size, expressed in sectors */ -+ /* FIXME: distinguish between kernel sector size and media sector size */ -+ size = device->size; -+ __copy_to_user ((long *) arg, &size, sizeof (long)); -+ return 0; -+#if 0 -+ case BLKFLSBUF: /* flush */ -+ return blk_ioctl(inode->i_rdev, cmd, arg); -+ case BLKRAGET: /* return the readahead value */ -+ return blk_ioctl(inode->i_rdev, cmd, arg); -+ case BLKRASET: /* set the readahead value */ -+ if (!capable (CAP_SYS_RAWIO)) -+ return -EACCES; -+ if (arg > 0xff) -+ return -EINVAL; /* limit it */ -+ return 0; -+// case BLKRRPART: /* re-read partition table */ -+// return sd_revalidate (inode->i_rdev); -+#endif -+ case HDIO_GETGEO: -+ /* -+ * get geometry: we have to fake one... trim the size to a -+ * multiple of 64 (32k): tell we have 16 sectors, 4 heads, -+ * whatever cylinders. Tell also that data starts at sector. 4. -+ */ -+ geo.cylinders = (device->size/4)/8; /* ?? only for test */ -+ geo.heads = 4; -+ geo.sectors = 8; -+ geo.start = 0; -+ __copy_to_user ((void *) arg, &geo, sizeof (geo)); -+ return 0; -+ default: -+ /* -+ * For ioctls we don't understand, let the block layer handle them. -+ */ -+ return -ENOTTY;//blk_ioctl (inode->i_rdev, cmd, arg); -+ } -+ -+ return -ENOTTY; /* unknown command */ -+} -+ -+static void sd_request(struct request_queue *q) -+{ -+ struct sd_dev *dev; -+ static int active; -+#ifndef A320_SD_USE_ASYNC_DMA -+ int ret; -+ struct request *req; -+#else -+ if(bh_busy) -+ return; -+#endif -+ if(active) -+ return; -+ active = 1; -+ P_DEBUG("--> %s\n", __func__); -+repeat: -+ /* Locate the device */ -+ if((req=blk_fetch_request(q))==NULL) { -+ active = 0; -+ return; -+ } -+ dev = req->rq_disk->private_data; -+ if (!dev||dev->card_state == SD_CARD_REMOVE) { -+ if(!dev) -+ printk(KERN_NOTICE"SD: locating device error\n"); -+ __blk_end_request_cur(req, -EIO); -+ goto repeat; -+ } -+#ifndef A320_SD_USE_ASYNC_DMA -+ sync_mode=1; -+ //spin_unlock_irq(&io_request_lock); -+ ret = sd_transfer(dev, req); -+ __blk_end_request(req, 0, ret << 9); -+ //spin_lock_irq(&io_request_lock); -+ goto repeat; -+ -+#else -+ sync_mode=0; //Use new async DMA machanism -+ //printk("%s: set up initial DMA, from sector %d to buffer 0x%X\n", __func__, CURRENT->sector+sector_offset, CURRENT->buffer); -+ //sd_init_async_dma(); -+ sd_clustered_bh(1); -+ //bh_busy=1; -+#endif -+ P_DEBUG("<-- %s\n", __func__); -+} -+ -+#if 0 -+/*----------------------------------------- -+ * Support for removable devices -+ */ -+int sd_check_change(kdev_t i_rdev) -+{ -+ int minor = DEVICE_NR(i_rdev); -+ struct sd_dev *dev = sd_devices + minor; -+ -+ P_DEBUG("--> %s\n", __func__); -+ P_DEBUG("minor=%d\n", minor); -+ if (minor >= SD_DEVS) /* paranoid */ -+ return 0; -+ P_DEBUG("check change for dev %d\n", minor); -+ if (dev->usage) { -+ P_DEBUG("disk not change\n"); -+ P_DEBUG("<-- %s\n", __func__); -+ return 0; /* still valid */ -+ } -+ P_DEBUG("disk changed\n"); -+ P_DEBUG("<-- %s\n", __func__); -+ return 1; /* expired */ -+} -+#endif -+ -+static int sd_dma_ch_alloc(struct sd_dev *dev) -+{ -+ dmad_chreq *ch_req = &dev->ch_req; -+ -+ memset(ch_req, 0, sizeof(dmad_chreq)); -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+ ch_req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */ -+/* for amerald */ -+ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID){ -+ ch_req->apb_req.addr0_reqn = APBBR_REQN_SDC_AMERALD; -+ }else -+ ch_req->apb_req.addr0_reqn = APBBR_REQN_SDC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ -+ ch_req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */ -+ ch_req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ -+ ch_req->apb_req.burst_mode = 1; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */ -+ ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */ -+ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ -+ -+ ch_req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ -+ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ memset(ch_req, 0, sizeof(dmad_chreq)); -+ printk(KERN_INFO "%s: APB dma channel allocation failed\n", __func__); -+ goto _try_ahb; -+ } -+ -+ P_DEBUG("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); -+ //printk("%s: APB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); -+ -+ return 0; -+ -+_try_ahb: -+ -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ -+ ch_req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */ -+ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */ -+ ch_req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */ -+ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */ -+ ch_req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ -+ ch_req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ -+ ch_req->ahb_req.addr0_reqn = DMAC_REQN_SDC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ -+ ch_req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ -+ ch_req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ -+ ch_req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ -+ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ -+ -+ ch_req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ -+ ch_req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ memset(ch_req, 0, sizeof(dmad_chreq)); -+ printk(KERN_INFO "%s: AHB dma channel allocation failed\n", __func__); -+ goto _err_exit; -+ } -+ -+ P_DEBUG("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); -+ //printk("%s: AHB dma channel allocated (ch: %d)\n", __func__, ch_req->channel); -+ -+ return 0; -+ -+_err_exit: -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+ return -ENODEV; -+} -+ -+/*-------------------------------- -+ * Note no locks taken out here. In a worst case scenario, we could drop -+ * a chunk of system memory. But that should never happen, since validation -+ * happens at open or mount time, when locks are held. -+ */ -+static int sd_revalidate(struct gendisk *gd) -+{ -+ struct sd_dev *dev = gd->private_data; -+ -+ P_DEBUG("--> %s\n", __func__); -+ P_DEBUG("card state=%s\n", dev->card_state == SD_CARD_INSERT ? "INSERT" : dev->card_state == SD_CARD_WORK ? "WORK" : "REMOVE"); -+ -+ if (dev->usage == 0) { -+ if (sd_card_setup(dev) != TRUE) { -+ dev->card_state = SD_CARD_REMOVE; -+ return -1; -+ } else { -+ enable_irq(FTSDC_IRQ); -+ dev->card_state = SD_CARD_WORK; -+ } -+ } -+ P_DEBUG("<-- %s\n", __func__); -+ -+ return 0; -+} -+ -+/* -+ * Device open and close -+ * TODO: forbids open for write when WRITE_PROTECT=1 -+ */ -+int sd_open(struct block_device *bdev, fmode_t mode) -+{ -+ struct sd_dev *dev= bdev->bd_disk->private_data; /* device information */ -+ P_DEBUG("--> %s\n", __func__); -+ /* Early return if there's nothing in the card slot */ -+ if ((SDC_R_REG(SDC_STATUS_REG) & SDC_STATUS_REG_CARD_INSERT) != SDC_CARD_INSERT) { -+ P_DEBUG("<-- %s (ENOMEDIUM)\n", __func__); -+ return -ENOMEDIUM; -+ } -+ //spin_lock(&dev->lock); -+ if (!dev->usage) { -+ dev->media_change=1; -+ P_DEBUG("%s: forced check_disk_change check\n", __func__); -+ check_disk_change(bdev); -+ sector_offset=0; -+ Do_onetime=0; -+ } else -+ dev->media_change=0; -+ -+ /* Set size HERE: -+ * must rely on sd_revalidate to set correct size -+ * (seems on check_disk_change()) */ -+ P_DEBUG("%s: set_capacity() to %d blocks (%d bytes)\n",__func__, dev->size, dev->size*SD_SECTOR_SIZE); -+ set_capacity(dev->gd, dev->size); -+ dev->usage++; -+ P_DEBUG("<-- %s\n", __func__); -+ -+ return 0; /* success */ -+} -+ -+int sd_release(struct gendisk *gd, fmode_t mode) -+{ -+ struct sd_dev *dev = gd->private_data; -+ -+ disable_irq(FTSDC_IRQ); -+ printk(" + sd_release : umount SD\n"); -+ -+ P_DEBUG("--> %s\n", __func__); -+ dev->usage--; -+ P_DEBUG("<-- %s\n", __func__); -+ -+ return 0; -+} -+ -+/*-------------------------------------- -+ * The file operations -+ */ -+struct block_device_operations sd_fops = { -+ owner: THIS_MODULE, -+ open: sd_open, -+ release: sd_release, -+ ioctl: sd_ioctl, -+ revalidate_disk: sd_revalidate, -+ media_changed: sd_media_changed, -+}; -+ -+void init_sd_pmu(void) -+{ -+ -+#ifdef CONFIG_FIE8100_PLATFORM -+ unsigned int u32temp; -+ u32temp = *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x14); -+ u32temp &= ~0x3000; -+ u32temp |= 0x2000; -+ *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x14)=u32temp; -+#endif -+ -+#ifdef CONFIG_FIE7000_PLATFORM -+ *(volatile unsigned int *)(A320_PMU_VA_BASE + 0x114) = (*(volatile unsigned int *)(A320_PMU_VA_BASE + 0x114) & 0xFFFF0FFF) | 0x00002000; -+#endif -+} -+ -+/* -+ * Set up our internal device. -+ */ -+static int setup_device(struct sd_dev *dev) -+{ -+ /* -+ * Get some memory. -+ */ -+ memset (dev, 0, sizeof (struct sd_dev)); -+ dev->size = 0;//SD_DUMMY_SIZE/SD_SECTOR_SIZE; /* We'll fill this with correct size later*/ -+ spin_lock_init(&dev->lock); -+ /* Request Queue */ -+ dev->queue = blk_init_queue(sd_request, &dev->lock); -+ if (dev->queue == NULL) -+ return -EFAULT; -+ -+ blk_queue_logical_block_size(dev->queue, hardsect_size); -+ dev->queue->queuedata = dev; -+ -+ dev->card_state = SD_CARD_REMOVE; -+ -+ /* -+ * And the gendisk structure. -+ */ -+ dev->gd = alloc_disk(SD_MINORS); -+ if (! dev->gd) { -+ printk (KERN_NOTICE "alloc_disk failure\n"); -+ return -EFAULT; -+ } -+ -+ dev->gd->flags = GENHD_FL_REMOVABLE|GENHD_FL_SUPPRESS_PARTITION_INFO; -+ dev->gd->major = sd_major; -+ dev->gd->first_minor = 0; -+ dev->gd->minors = SD_MINORS; -+ dev->gd->fops = &sd_fops; -+ dev->gd->queue = dev->queue; -+ dev->gd->private_data = dev; -+ snprintf (dev->gd->disk_name, 32, "cpesd%c", 'a'); -+ set_capacity(dev->gd, 0); //SD_DUMMY_SIZE/SD_SECTOR_SIZE*(hardsect_size/KERNEL_SECTOR_SIZE)); -+ add_disk(dev->gd); -+ -+ /* -+ * dma alloc -+ */ -+ if (sd_dma_ch_alloc(dev) == 0) { -+ printk(KERN_NOTICE "Faraday SD controller Driver (DMA mode)\n"); -+ dev->dma_enable = true; -+ } else { -+ printk(KERN_NOTICE "Faraday SD controller Driver (PIO mode)\n"); -+ } -+ -+ return 0; -+} -+/* -+ * Look for a media change. -+ */ -+static int sd_media_changed(struct gendisk *gd) -+{ -+ struct sd_dev *dev = gd->private_data; -+ return dev->media_change; -+} -+ -+/* -+ * module stuff -+ */ -+static int __init sd_module_init(void) -+{ -+ int result=-ENOMEM; -+ spinlock_t complete_lock; -+ unsigned long iflags; -+ spin_lock_init(&complete_lock); -+ -+#ifdef CONFIG_PLAT_QEMU -+ SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(0x44) & 0xff; -+#else -+ if(SDC_R_REG(0xa0) == 0x00030101) -+ SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(0x9c) & 0xff; -+ else -+ SDC_READ_FIFO_LEN = SDC_WRITE_FIFO_LEN = SDC_R_REG(SDC_FEATURE_REG) & 0xff; -+#endif -+ /* Register SD driver */ -+ sd_major = register_blkdev(sd_major, DEVICE_NAME); -+ if (sd_major <= 0) { -+ printk(KERN_WARNING DEVICE_NAME ":unable to get major number\n"); -+ return -EBUSY; -+ } -+ init_sd_pmu(); /* Power on SDC */ -+ P_DEBUG("SD Major Number = %d\n", sd_major); -+ printk(KERN_ALERT "SD: make node with 'mknod /dev/cpesd b %d 0'\n", sd_major); -+ -+ sd_devices = kmalloc(sizeof(struct sd_dev), GFP_KERNEL); -+ if (!sd_devices) -+ goto fail_malloc; -+ memset(sd_devices, 0, sizeof(struct sd_dev)); -+ -+ if (setup_device(sd_devices)) -+ goto fail_malloc; -+ -+ P_DEBUG("Request SDC IRQ=%d\n", FTSDC_IRQ); -+ spin_lock_irqsave(&complete_lock, iflags); -+ if (request_irq(FTSDC_IRQ, sd_hotswap_interrupt_handler, IRQF_DISABLED, "SD controller", sd_devices) != 0) { -+ printk(KERN_ERR "Unable to allocate SDC IRQ=0x%X\n", FTSDC_IRQ); -+ goto fail_malloc; -+ } -+ disable_irq(FTSDC_IRQ); -+ spin_unlock_irqrestore(&complete_lock, iflags); -+ if (request_region(FTSDC_VA_BASE, 0x48, "SD Controller") == NULL) { -+ printk(KERN_ERR "request io port of sd controller fail\n"); -+ goto fail_mem; -+ } -+ -+ return 0; /* succeed */ -+ -+fail_mem: -+ free_irq(FTSDC_IRQ, sd_devices); -+ -+fail_malloc: -+ if (sd_devices) -+ kfree(sd_devices); -+ unregister_blkdev(sd_major, DEVICE_NAME); -+ return result; -+} -+ -+static void sd_module_cleanup(void) -+{ -+ P_DEBUG("--> %s\n", __func__); -+ -+ /* unregister the device now to avoid further operations during cleanup */ -+ -+ if (sd_devices) { -+ del_gendisk(sd_devices->gd); -+ put_disk(sd_devices->gd); -+ if(sd_devices->queue) -+ blk_cleanup_queue(sd_devices->queue); -+ -+ if (sd_devices->dma_enable) -+ dmad_channel_free(&sd_devices->ch_req); -+ -+ kfree(sd_devices); -+ } -+ -+ release_region(FTSDC_VA_BASE, 0x48); -+ free_irq(FTSDC_IRQ, sd_devices); -+ -+ unregister_blkdev(sd_major, DEVICE_NAME); -+ P_DEBUG("<-- %s\n", __func__); -+} -+ -+module_init(sd_module_init); -+module_exit(sd_module_cleanup); -diff -Nur linux-3.4.113.orig/drivers/block/ftsdc010.h linux-3.4.113/drivers/block/ftsdc010.h ---- linux-3.4.113.orig/drivers/block/ftsdc010.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/block/ftsdc010.h 2016-12-01 20:59:24.384613985 +0100 -@@ -0,0 +1,477 @@ -+/* drivers/block/CPESD/ftsdc010.h -+ * -+ * Faraday FTSDC010 Device Driver -+ * -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * All Rights Reserved -+ */ -+ -+#ifndef _FTSDC010_H_ -+#define _FTSDC010_H_ -+ -+#ifndef TRUE -+#define TRUE 1 -+#endif -+ -+#ifndef FALSE -+#define FALSE 0 -+#endif -+ -+//#define SD_DEBUG -+#define DELAY_FOR_DMA_READ -+ -+#ifdef SD_DEBUG -+ #define P_DEBUG(fmt, args...) printk(KERN_ALERT "SD: " fmt, ## args) -+#else -+ #define P_DEBUG(a...) -+#endif -+#define P_DEBUGG(a...) -+ -+#define MAX_READ_SECTOR_NR 96 //16 -+#define MAX_WRITE_SECTOR_NR MAX_READ_SECTOR_NR -+ -+#define SD_MAJOR 6 /* default major number, if zero, it means dynamic allocate */ -+#define SD_DEVS 1 /* number of disks */ -+#define SD_MINORS 16 /* minors per disk */ -+#define SD_RAHEAD 2 /* number of sectors */ -+#define SD_BLKSIZE 1024 /* block size */ -+#define SD_SECTOR_SIZE 512 /* sector size */ -+#define SD_DUMMY_SIZE (256*1024*1024) // for sake of hotswap/hotplug -+#if 0 -+typedef struct _sd_dev_t { -+ int size; -+ int usage; -+ //struct timer_list timer; -+ spinlock_t lock; -+ struct semaphore sema; // synchronization -+ int card_state; -+} sd_dev_t; -+#endif -+//---------SD Card State -+#define SD_CARD_REMOVE 0 -+#define SD_CARD_INSERT 1 -+#define SD_CARD_WORK 2 -+ -+/* so far, SD controller support 3.2-3.3 VDD */ -+#define SDC_OCR 0x00FF8000 -+ -+/* sd controller register */ -+#define SDC_CMD_REG 0x00000000 -+#define SDC_ARGU_REG 0x00000004 -+#define SDC_RESPONSE0_REG 0x00000008 -+#define SDC_RESPONSE1_REG 0x0000000C -+#define SDC_RESPONSE2_REG 0x00000010 -+#define SDC_RESPONSE3_REG 0x00000014 -+#define SDC_RSP_CMD_REG 0x00000018 -+#define SDC_DATA_CTRL_REG 0x0000001C -+#define SDC_DATA_TIMER_REG 0x00000020 -+#define SDC_DATA_LEN_REG 0x00000024 -+#define SDC_STATUS_REG 0x00000028 -+#define SDC_CLEAR_REG 0x0000002C -+#define SDC_INT_MASK_REG 0x00000030 -+#define SDC_POWER_CTRL_REG 0x00000034 -+#define SDC_CLOCK_CTRL_REG 0x00000038 -+#define SDC_BUS_WIDTH_REG 0x0000003C -+#define SDC_DATA_WINDOW_REG 0x00000040 -+#ifdef A320D_BUILDIN_SDC -+#define SDC_FEATURE_REG 0x00000044 -+#define SDC_REVISION_REG 0x00000048 -+#else -+#define SDC_MMC_INT_RSP_REG 0x00000044 -+#define SDC_GP_OUTPUT_REG 0x00000048 -+#define SDC_FEATURE_REG 0x0000009C -+#define SDC_REVISION_REG 0x000000A0 -+#endif -+ -+/* bit mapping of command register */ -+#define SDC_CMD_REG_INDEX 0x0000003F -+#define SDC_CMD_REG_NEED_RSP 0x00000040 -+#define SDC_CMD_REG_LONG_RSP 0x00000080 -+#define SDC_CMD_REG_APP_CMD 0x00000100 -+#define SDC_CMD_REG_CMD_EN 0x00000200 -+#define SDC_CMD_REG_SDC_RST 0x00000400 -+ -+/* bit mapping of response command register */ -+#define SDC_RSP_CMD_REG_INDEX 0x0000003F -+#define SDC_RSP_CMD_REG_APP 0x00000040 -+ -+/* bit mapping of data control register */ -+#define SDC_DATA_CTRL_REG_BLK_SIZE 0x0000000F -+#define SDC_DATA_CTRL_REG_DATA_WRITE 0x00000010 -+#define SDC_DATA_CTRL_REG_DATA_READ 0x00000000 -+#define SDC_DATA_CTRL_REG_DMA_EN 0x00000020 -+#define SDC_DATA_CTRL_REG_DATA_EN 0x00000040 -+ -+#define SDC_DMA_TYPE_1 0x00000000 -+#define SDC_DMA_TYPE_4 0x00000100 -+#define SDC_DMA_TYPE_8 0x00000200 -+ -+/* bit mapping of status/clear/mask register */ -+#define SDC_STATUS_REG_RSP_CRC_FAIL 0x00000001 -+#define SDC_STATUS_REG_DATA_CRC_FAIL 0x00000002 -+#define SDC_STATUS_REG_RSP_TIMEOUT 0x00000004 -+#define SDC_STATUS_REG_DATA_TIMEOUT 0x00000008 -+#define SDC_STATUS_REG_RSP_CRC_OK 0x00000010 -+#define SDC_STATUS_REG_DATA_CRC_OK 0x00000020 -+#define SDC_STATUS_REG_CMD_SEND 0x00000040 -+#define SDC_STATUS_REG_DATA_END 0x00000080 -+#define SDC_STATUS_REG_FIFO_UNDERRUN 0x00000100 -+#define SDC_STATUS_REG_FIFO_OVERRUN 0x00000200 -+#define SDC_STATUS_REG_CARD_CHANGE 0x00000400 -+#define SDC_STATUS_REG_CARD_INSERT 0x00000800 -+#define SDC_STATUS_REG_CARD_LOCK 0x00001000 -+ -+#define SDC_CARD_INSERT 0x0 -+#define SDC_CARD_REMOVE SDC_STATUS_REG_CARD_INSERT -+ -+/* bit mapping of power control register */ -+#define SDC_POWER_REG_POWER_ON 0x00000010 -+#define SDC_POWER_REG_POWER_BITS 0x0000000F -+ -+/* bit mapping of clock control register */ -+#define SDC_CLOCK_REG_CARD_TYPE 0x00000080 -+#define SDC_CLOCK_REG_CLK_DIV 0x0000007F -+ -+/* card type */ -+#define SDC_CARD_TYPE_SD SDC_CLOCK_REG_CARD_TYPE -+#define SDC_CARD_TYPE_MMC 0x0 -+ -+/* bit mapping of bus width register */ -+#define SDC_BUS_WIDTH_REG_SINGLE_BUS 0x00000001 -+#define SDC_BUS_WIDTH_REG_WIDE_BUS 0x00000004 -+#define SDC_WIDE_BUS_SUPPORT 0x00000008 -+ -+/* data window register */ -+//#define SDC_READ_FIFO_LEN 4 -+//#define SDC_WRITE_FIFO_LEN 4 -+ -+/* card type, sd or mmc */ -+#define MEMORY_CARD_TYPE_SD 0 -+#define MEMORY_CARD_TYPE_MMC 1 -+ -+/********************************************************************/ -+/* SYSTEM ERROR_CODE */ -+/********************************************************************/ -+#define ERR_NO_ERROR 0x00000000 -+ -+/* general error */ -+#define ERR_CARD_NOT_EXIST 0x00000001 -+#define ERR_OUT_OF_VOLF_RANGE 0x00000002 -+#define ERR_SD_PARTITIAL_READ_ERROR 0x00000004 -+#define ERR_SD_PARTITIAL_WRITE_ERROR 0x00000008 -+ -+#define ERR_SD_CARD_IS_LOCK 0x00000010 -+ -+/* command error */ -+#define ERR_DATA_CRC_ERROR 0x00000100 -+#define ERR_RSP_CRC_ERROR 0x00000200 -+#define ERR_DATA_TIMEOUT_ERROR 0x00000400 -+#define ERR_RSP_TIMEOUT_ERROR 0x00000800 -+ -+#define ERR_WAIT_OVERRUN_TIMEOUT 0x00001000 -+#define ERR_WAIT_UNDERRUN_TIMEOUT 0x00002000 -+#define ERR_WAIT_DATA_CRC_TIMEOUT 0x00004000 -+#define ERR_WAIT_TRANSFER_END_TIMEOUT 0x00008000 -+ -+#define ERR_SEND_COMMAND_TIMEOUT 0x00010000 -+ -+/* sd error */ -+#define ERR_SD_CARD_IS_BUSY 0x00100000 -+#define ERR_CID_REGISTER_ERROR 0x00200000 -+#define ERR_CSD_REGISTER_ERROR 0x00400000 -+ -+/* sd card status error */ -+#define ERR_SD_CARD_STATUS_ERROR 0x01000000 -+/* SDC using APB DMA error */ -+#define ERR_DMA_RSP_ERROR 0x02000000 -+ -+#define SD_SCR_1_BIT_BIT 0x0001 -+#define SD_SCR_4_BIT_BIT 0x0004 -+ -+/********************************************************************/ -+/* The bit mapping of SD Status register */ -+/********************************************************************/ -+#define SD_STATUS_OUT_OF_RANGE 0x80000000 -+#define SD_STATUS_ADDRESS_ERROR 0x40000000 -+#define SD_STATUS_BLOCK_LEN_ERROR 0x20000000 -+#define SD_STATUS_ERASE_SEQ_ERROR 0x10000000 -+#define SD_STATUS_ERASE_PARAM 0x08000000 -+#define SD_STATUS_WP_VIOLATION 0x04000000 -+#define SD_STATUS_CARD_IS_LOCK 0x02000000 -+#define SD_STATUS_LOCK_UNLOCK_FILED 0x01000000 -+#define SD_STATUS_COM_CRC_ERROR 0x00800000 -+#define SD_STATUS_ILLEGAL_COMMAND 0x00400000 -+#define SD_STATUS_CARD_ECC_FAILED 0x00200000 -+#define SD_STATUS_CC_ERROR 0x00100000 -+#define SD_STATUS_ERROR 0x00080000 -+#define SD_STATUS_UNDERRUN 0x00040000 -+#define SD_STATUS_OVERRUN 0x00020000 -+#define SD_STATUS_CID_CSD_OVERWRITE 0x00010000 -+#define SD_STATUS_WP_ERASE_SKIP 0x00008000 -+#define SD_STATUS_CARD_ECC_DISABLE 0x00004000 -+#define SD_STATUS_ERASE_RESET 0x00002000 -+#define SD_STATUS_CURRENT_STATE 0x00001E00 -+#define SD_STATUS_READY_FOR_DATA 0x00000100 -+#define SD_STATUS_APP_CMD 0x00000020 -+#define SD_STATUS_AKE_SEQ_ERROR 0x00000008 -+#define SD_STATUS_ERROR_BITS (SD_STATUS_ADDRESS_ERROR | SD_STATUS_BLOCK_LEN_ERROR | SD_STATUS_ERASE_SEQ_ERROR | SD_STATUS_ERASE_PARAM | SD_STATUS_WP_VIOLATION | SD_STATUS_LOCK_UNLOCK_FILED | SD_STATUS_CARD_ECC_FAILED | SD_STATUS_CC_ERROR | SD_STATUS_ERROR | SD_STATUS_UNDERRUN | SD_STATUS_OVERRUN | SD_STATUS_CID_CSD_OVERWRITE | SD_STATUS_WP_ERASE_SKIP | SD_STATUS_AKE_SEQ_ERROR) -+#define SD_STATUS_CURRENT_STATE_LOC 9 -+ -+/********************************************************************/ -+/* SD command response type */ -+/********************************************************************/ -+#define SD_NO_RESPONSE 0 -+#define SD_RESPONSE_R1 1 -+#define SD_RESPONSE_R1b 2 -+#define SD_RESPONSE_R2 3 -+#define SD_RESPONSE_R3 4 -+#define SD_RESPONSE_R6 5 -+ -+/********************************************************************/ -+/* SD command */ -+/********************************************************************/ -+#define SD_GO_IDLE_STATE_CMD 0 -+#define SD_MMC_OP_COND 1 -+#define SD_ALL_SEND_CID_CMD 2 -+#define SD_SEND_RELATIVE_ADDR_CMD 3 -+#define SD_SET_DSR_CMD 4 -+#define SD_SET_BUS_WIDTH_CMD 6 -+#define SD_SELECT_CARD_CMD 7 -+#define SD_SEND_CSD_CMD 9 -+#define SD_SEND_CID_CMD 10 -+#define SD_STOP_TRANSMISSION_CMD 12 -+#define SD_SEND_STATUS_CMD 13 -+#define SD_GO_INACTIVE_STATE_CMD 15 -+#define SD_SET_BLOCKLEN_CMD 16 -+#define SD_READ_SINGLE_BLOCK_CMD 17 -+#define SD_READ_MULTIPLE_BLOCK_CMD 18 -+#define SD_WRITE_SINGLE_BLOCK_CMD 24 -+#define SD_WRITE_MULTIPLE_BLOCK_CMD 25 -+#define SD_PROGRAM_CSD_CMD 27 -+#define SD_ERASE_SECTOR_START_CMD 32 -+#define SD_ERASE_SECTOR_END_CMD 33 -+#define SD_ERASE_CMD 38 -+#define SD_APP_OP_COND 41 -+#define SD_LOCK_UNLOCK_CMD 42 -+#define SD_SEND_SCR_CMD 51 -+#define SD_APP_CMD 55 -+#define SD_GET_CMD 56 -+ -+/* retry count */ -+#ifndef CONFIG_FTSDC010_USE_TIMER_DELAY -+#define SD_CARD_GET_OCR_RETRY_COUNT 0x1000 -+#define SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT 8000 -+#define SD_CARD_STATE_CHANGE_RETRY_COUNT 30000 -+#define SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT 30000 -+#define SDC_GET_STATUS_RETRY_COUNT 0x300000 -+#else -+#define SD_CARD_GET_OCR_RETRY_COUNT 0x1000 -+#define SD_CARD_WAIT_OPERATION_COMPLETE_RETRY_COUNT 8000 -+#define SD_CARD_STATE_CHANGE_RETRY_COUNT 10000 -+#define SD_CARD_WAIT_TRANSFER_STATE_RETRY_COUNT 10000 -+#endif -+ -+/* -+ * Please refer SanDisk SD Manual v1.9 Section 5.1.9.2 (page 5-76) to set the timeout setting -+ */ -+#ifdef SD_DEBUG -+#define SDC_TIMEOUT_BASE (HZ/2) // Unit is 500 ms -+#else -+#define SDC_TIMEOUT_BASE (HZ/3) // Unit is 333 ms -+#endif -+#define SDC_GET_STATUS_RETRY_TIMEOUT_COUNT (HZ*4) -+ -+/* sd card standby state */ -+#define SD_IDLE_STATE 0 -+#define SD_READY_STATE 1 -+#define SD_IDENT_STATE 2 -+#define SD_STBY_STATE 3 -+#define SD_TRAN_STATE 4 -+#define SD_DATA_STATE 5 -+#define SD_RCV_STATE 6 -+#define SD_PRG_STATE 7 -+#define SD_DIS_STATE 8 -+ -+#define SD_BUS_WIDTH_1_BIT 0 -+#define SD_BUS_WIDTH_4_BIT 2 -+ -+/********************************************************************/ -+/* SD card OCR register */ -+/********************************************************************/ -+#define SD_OCR_BUSY_BIT 0x80000000 -+ -+/********************************************************************/ -+/* SD CID register */ -+/********************************************************************/ -+#define SD_DEFAULT_MONTH_CODE 1 -+#define SD_DEFAULT_YEAR_CODE 2000 -+#define MAX_MULTI_BLOCK_NUM 126 -+ -+typedef struct _sd_cid_t -+{ -+ uint ManufacturerID; -+ uint ApplicationID; -+ unchar ProductName[7]; -+ uint ProductRevisionHigh; -+ uint ProductRevisionLow; -+ uint ProductSerialNumber; -+ uint ManufactureMonth; -+ uint ManufactureYear; -+} sd_cid_t; -+ -+/********************************************************************/ -+/* SD CSD register */ -+/********************************************************************/ -+#define SD_CSD_STRUCTURE_1_0 0 -+#define SD_CSD_STRUCTURE_1_1 1 -+ -+#define SD_CSD_SPEC_VERS_1_0_1_2 0 -+#define SD_CSD_SPEC_VERS_1_4 1 -+#define SD_CSD_SPEC_VERS_2_1 2 -+ -+#define SD_TAAC_TIME_UINT_BITS 0x07 -+#define SD_TAAC_TIME_VALUE_BITS 0x78 -+ -+typedef struct _sd_csd_t -+{ -+ uint CSDStructure; -+ uint MMCSpecVersion; -+ uint TAAC_u; -+ uint NSAC_u; -+ uint TransferSpeed; -+ uint CardCmdClass; -+ uint ReadBlockLength; -+ uint ReadBlockPartial; -+ uint WriteBlockMisalign; -+ uint ReadBlockMisalign; -+ uint DSRImplemant; -+ uint BlockNumber; -+ uint MemorySize; -+ uint VDDReadMin_u; -+ uint VDDReadMax_u; -+ uint VDDWriteMin_u; -+ uint VDDWriteMax_u; -+ uint EraseBlkEnable; -+ uint EraseSectorSize; -+ uint WriteProtectGroupSize; -+ uint WriteProtectGroupEnable; -+ uint WriteSpeedFactor; -+ uint WriteBlockLength; -+ unchar WriteBlockPartial; -+ unchar CopyFlag; -+ unchar PermanentWriteProtect; -+ unchar TemporaryWriteProtect; -+ unchar FileFormat; -+} sd_csd_t; -+ -+typedef struct _sd_csd_bit_t -+{ -+ uint NotUsed:1; -+ uint CRC:7; -+ uint MMCardReserved1:2; -+ uint FILE_FORMAT:2; -+ uint TMP_WRITE_PROTECT:1; -+ uint PERM_WRITE_PROTECT:1; -+ uint COPY:1; -+ uint FILE_FORMAT_GRP:1; -+ -+ uint Reserved2:5; -+ uint WRITE_BL_PARTIAL:1; -+ uint WRITE_BL_LEN:4; -+ uint R2W_FACTOR:3; -+ uint MMCardReserved0:2; -+ uint WP_GRP_ENABLE:1; -+ -+ uint WP_GRP_SIZE:7; -+ uint ERASE_SECTOR_SIZE:7; -+ uint ERASE_BLK_ENABLE:1; -+ uint C_SIZE_MULT:3; -+ uint VDD_W_CURR_MAX:3; -+ uint VDD_W_CURR_MIN:3; -+ uint VDD_R_CURR_MAX:3; -+ uint VDD_R_CURR_MIN:3; -+ -+ uint C_SIZE_1:2; -+ uint C_SIZE_2:10; // divide its into 2, 10bits -+ -+ uint Reserved1:2; -+ uint DSR_IMP:1; -+ uint READ_BLK_MISALIGN:1; -+ uint WRITE_BLK_MISALIGN:1; -+ uint READ_BL_PARTIAL:1; -+ -+ uint READ_BL_LEN:4; -+ uint CCC:12; -+ -+ uint TRAN_SPEED_RateUnit:3; -+ uint TRAN_SPEED_TimeValue:4; -+ uint TRAN_SPEED_Reserved:1; -+ -+ uint NSAC:8; -+ -+ uint TAAC_TimeUnit:3; -+ uint TAAC_TimeValue:4; -+ uint TAAC_Reserved:1; -+ -+ uint Reserved0:2; -+ uint MMC_SPEC_VERS:4; -+ uint CSD_STRUCTURE:2; -+} sd_csd_bit_t; -+ -+/********************************************************************/ -+/* SD SCR register */ -+/********************************************************************/ -+typedef struct _sd_scr_t -+{ -+ uint Reserved:16; -+ uint SD_BUS_WIDTH:4; -+ uint SD_SECURITY:3; -+ uint DATA_STAT_AFTER_ERASE:1; -+ uint SD_SPEC:4; -+ uint SCR_STRUCTURE:4; -+ -+ uint ManufacturerReserved; -+} sd_scr_t; -+ -+/********************************************************************/ -+/* sd card structure */ -+/********************************************************************/ -+typedef struct _sd_card_t -+{ -+ /* host interface configuration */ -+ uint IOAddr; /* host controller register base address */ -+ uint DMAEnable; -+ -+ uint CardType; -+ -+ /* card register */ -+ uint OCR; -+ -+ uint CIDWord[4]; -+ sd_cid_t CID; -+ -+ uint CSDWord[4]; -+ sd_csd_t CSD; -+ -+ ushort RCA; -+ sd_scr_t SCR; -+ -+ /* access time out */ -+ uint ReadAccessTimoutCycle; -+ uint WriteAccessTimoutCycle; -+ -+ /* Drive Name */ -+ uint Drive; -+ -+ /* system configurations */ -+ uint SysFrequency; -+ -+ /* card status */ -+ int ActiveState; -+ int WriteProtect; -+ -+ void *private; -+} sd_card_t; -+ -+#endif -diff -Nur linux-3.4.113.orig/drivers/block/Kconfig linux-3.4.113/drivers/block/Kconfig ---- linux-3.4.113.orig/drivers/block/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/block/Kconfig 2016-12-01 20:59:24.384613985 +0100 -@@ -498,6 +498,14 @@ - block device driver. It communicates with a back-end driver - in another domain which drives the actual block device. - -+config FTSDC010 -+ tristate "Faraday FTSDC010 driver" -+ depends on NDS32 -+ -+config FTCFC010 -+ tristate "Faraday FTCFC010 driver" -+ depends on NDS32 -+ - config XEN_BLKDEV_BACKEND - tristate "Xen block-device backend driver" - depends on XEN_BACKEND -diff -Nur linux-3.4.113.orig/drivers/block/Makefile linux-3.4.113/drivers/block/Makefile ---- linux-3.4.113.orig/drivers/block/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/block/Makefile 2016-12-01 20:59:24.384613985 +0100 -@@ -43,3 +43,5 @@ - obj-$(CONFIG_BLK_DEV_PCIESSD_MTIP32XX) += mtip32xx/ - - swim_mod-y := swim.o swim_asm.o -+obj-$(CONFIG_FTSDC010) += ftsdc010.o -+obj-$(CONFIG_FTCFC010) += ftcfc010.o -diff -Nur linux-3.4.113.orig/drivers/gpio/gpio-ftgpio010.c linux-3.4.113/drivers/gpio/gpio-ftgpio010.c ---- linux-3.4.113.orig/drivers/gpio/gpio-ftgpio010.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/gpio/gpio-ftgpio010.c 2016-12-01 20:59:24.384613985 +0100 -@@ -0,0 +1,218 @@ -+#include -+#include -+#include -+#include -+#include -+ -+#define GPIO_DATA_OUT 0x00 -+#define GPIO_DATA_IN 0x04 -+#define PIN_DIR 0x08 -+#define PIN_BYPASS 0x0C -+#define GPIO_DATA_SET 0x10 -+#define GPIO_DATA_CLEAR 0x14 -+#define PIN_PULL_ENABLE 0x18 -+#define PIN_PULL_TYPE 0x1C -+#define INT_ENABLE 0x20 -+#define INT_RAW_STATE 0x24 -+#define INT_MASKED_STATE 0x28 -+#define INT_MASK 0x2C -+#define INT_CLEAR 0x30 -+#define INT_TRIGGER 0x34 -+#define INT_BOTH 0x38 -+#define INT_RISE_NEG 0x3C -+#define BOUNCE_ENABLE 0x40 -+#define BOUNCE_PRE_SCALE 0x44 -+ -+#define GPIO_READL(offset) \ -+ readl(GPIO_FTGPIO010_VA_BASE + (offset)) -+ -+#define GPIO_WRITEL(val, offset) \ -+ writel((val), GPIO_FTGPIO010_VA_BASE + (offset)) -+ -+#define FTGPIO010_VIRTUAL_IRQ_BASE 100 -+ -+static int irq_to_gpio(unsigned int irq) -+{ -+ return irq - FTGPIO010_VIRTUAL_IRQ_BASE; -+} -+ -+static int ftgpio_to_irq(struct gpio_chip *gc, unsigned int offset) -+{ -+ return FTGPIO010_VIRTUAL_IRQ_BASE + offset; -+} -+ -+static int ftgpio_get(struct gpio_chip *gc, unsigned int gpio) -+{ -+ return (GPIO_READL(GPIO_DATA_IN) >> gpio & 1); -+} -+ -+static void ftgpio_set(struct gpio_chip *gc, unsigned int gpio, int data) -+{ -+ unsigned long val; -+ -+ if (data) -+ val = GPIO_READL(GPIO_DATA_OUT) | (0x1UL << gpio); -+ else -+ val = GPIO_READL(GPIO_DATA_OUT) & ~(0x1UL << gpio); -+ -+ GPIO_WRITEL(val, GPIO_DATA_OUT); -+} -+ -+static int ftgpio_dir_in(struct gpio_chip *gc, unsigned int gpio) -+{ -+ unsigned long val; -+ -+ val = GPIO_READL(PIN_DIR) & ~(0x1UL << gpio); -+ GPIO_WRITEL(val, PIN_DIR); -+ -+ return 0; -+} -+ -+static int ftgpio_dir_out(struct gpio_chip *gc, unsigned int gpio, int data) -+{ -+ unsigned long val; -+ -+ val = GPIO_READL(PIN_DIR) | (0x1UL << gpio); -+ GPIO_WRITEL(val, PIN_DIR); -+ -+ gc->set(gc, gpio, data); -+ -+ return 0; -+} -+ -+static struct gpio_chip ftgpio_chip = { -+ -+ .label = "FTGPIO010", -+ .base = 0, -+ .ngpio = 16, -+ .direction_input = ftgpio_dir_in, -+ .direction_output = ftgpio_dir_out, -+ .get = ftgpio_get, -+ .set = ftgpio_set, -+ .to_irq = ftgpio_to_irq, -+}; -+ -+static void ftgpio_irq_ack(struct irq_data *data) -+{ -+ GPIO_WRITEL(0x1UL << irq_to_gpio(data->irq), INT_CLEAR); -+} -+ -+static void ftgpio_irq_mask(struct irq_data *data) -+{ -+ unsigned long val; -+ -+ val = GPIO_READL(INT_MASK) | (0x1UL << irq_to_gpio(data->irq)); -+ GPIO_WRITEL(val, INT_MASK); -+} -+ -+static void ftgpio_irq_unmask(struct irq_data *data) -+{ -+ unsigned long val; -+ val = GPIO_READL(INT_MASK) & ~(0x1UL << irq_to_gpio(data->irq)); -+ GPIO_WRITEL(val, INT_MASK); -+} -+ -+static int ftgpio_irq_set_type(struct irq_data *data, unsigned int flow_type) -+{ -+ unsigned long bit = 0x1UL << irq_to_gpio(data->irq); -+ unsigned long val; -+ val = GPIO_READL(INT_BOTH); -+ -+ if (flow_type & IRQF_TRIGGER_RISING && flow_type & IRQF_TRIGGER_FALLING) -+ GPIO_WRITEL(val | bit, INT_BOTH); -+ else -+ GPIO_WRITEL(val & ~bit, INT_BOTH); -+ -+ val = GPIO_READL(INT_RISE_NEG); -+ -+ if (flow_type & IRQF_TRIGGER_FALLING) -+ GPIO_WRITEL(val | bit, INT_RISE_NEG); -+ else if (flow_type & IRQF_TRIGGER_RISING) -+ GPIO_WRITEL(val & ~bit, INT_RISE_NEG); -+ -+ return 0; -+} -+ -+static struct irq_chip ftgpio_irq_chip = { -+ -+ .name = "FTGPIO010_irq", -+ .irq_ack = ftgpio_irq_ack, -+ .irq_mask = ftgpio_irq_mask, -+ .irq_unmask = ftgpio_irq_unmask, -+ .irq_set_type = ftgpio_irq_set_type, -+}; -+ -+static void gpio_irq_router(unsigned int irq, struct irq_desc *desc) -+{ -+ unsigned long status; -+ int i = 0; -+ -+ status = GPIO_READL(INT_RAW_STATE); -+ status &= ~((1 << 22) | (1 << 25) | (1 << 26)); -+ -+ while (status) { -+ -+ if (status & 0x1UL) -+ generic_handle_irq(gpio_to_irq(i)); -+ -+ status >>= 1; -+ i++; -+ } -+} -+ -+static int gpio_init(void) -+{ -+ int i; -+ -+ /* disable interrupt */ -+ GPIO_WRITEL(0x00000000UL, INT_ENABLE); -+ -+ /* mask interrupt */ -+ GPIO_WRITEL(0x0000FFFFUL, INT_MASK); -+ -+ /* triggered interrupt on both edge */ -+ GPIO_WRITEL(0x0000FFFFUL, INT_BOTH); -+ -+ /* clear interrupt */ -+ GPIO_WRITEL(0x0000FFFFUL, INT_CLEAR); -+ -+ /* enable de-bouncing */ -+ GPIO_WRITEL(0x0000FFFFUL, BOUNCE_ENABLE); -+ -+ /* enable interrupt */ -+ GPIO_WRITEL(0x0000FFFFUL, INT_ENABLE); -+ -+ gpiochip_add(&ftgpio_chip); -+ -+ for (i = 0; i < ftgpio_chip.ngpio; i++) { -+ -+ irq_set_chip(gpio_to_irq(i), &ftgpio_irq_chip); -+ irq_set_handler(gpio_to_irq(i), handle_level_irq); -+ } -+ -+ irq_set_chained_handler(GPIO_FTGPIO010_IRQ, gpio_irq_router); -+ -+ pr_info("GPIO module inserted\n"); -+ -+ return 0; -+} -+ -+static void __exit gpio_exit(void) -+{ -+ int i=0; -+ /* disable interrupt */ -+ GPIO_WRITEL(0x00000000UL, INT_ENABLE); -+ while(i -+#include -+#include -+#include -+ -+#include -+#include "cpe_ts.h" -+ -+ -+#include -+ -+#include -+#include -+ -+#define TOUCHSCREEN_IRQ 28 -+ -+#define ads_dbg( enabled, tagged, ...) \ -+ do{ \ -+ if( enabled){ \ -+ if( tagged) \ -+ printk( "[ %30s() ] ", __func__); \ -+ printk( __VA_ARGS__); \ -+ } \ -+ } while( 0) -+ -+#define TS_POLL_DELAY ( 1 * 1000000) /* ns delay before the first sample */ -+#define TS_POLL_PERIOD ( delay * 1000000) /* ns delay between samples */ -+ -+static int debug = 0; -+static int delay = 25; -+ -+module_param(debug, int, 0); -+module_param(delay, int, 0); -+ -+struct ads7846 -+{ -+ void __iomem * regs; -+ struct input_dev *input; -+ char phys[32]; -+ struct hrtimer timer; -+ int irq; -+ spinlock_t lock; -+ bool disabled; -+}; -+ -+struct ts_event -+{ -+ int x; -+ int y; -+ int z1, z2; -+ int Rt; -+}; -+ -+struct ads7846 touchscreen; -+ -+#define ADS_START ( 0x1UL << 7) -+#define ADS_A2A1A0_d_y ( 0x1UL << 4) /* differential */ -+#define ADS_A2A1A0_d_z1 ( 0x3UL << 4) /* differential */ -+#define ADS_A2A1A0_d_z2 ( 0x4UL << 4) /* differential */ -+#define ADS_A2A1A0_d_x ( 0x5UL << 4) /* differential */ -+#define ADS_12_BIT ( 0x0UL << 3) -+#define ADS_SER ( 0x1UL << 2) /* non-differential */ -+#define ADS_DFR ( 0x0UL << 2) /* differential */ -+#define ADS_PD10_PDOWN ( 0x0UL << 0) /* lowpower mode + penirq */ -+#define ADS_PD10_ADC_ON ( 0x1UL << 0) /* ADC on */ -+#define ADS_PD10_REF_ON ( 0x2UL << 0) /* vREF on + penirq */ -+#define ADS_PD10_ALL_ON ( 0x3UL << 0) /* ADC + vREF on */ -+ -+#define MAX_12BIT ( ( 0x1UL << 12) - 1) -+ -+#define READ_X ( ADS_A2A1A0_d_x | ADS_12_BIT | ADS_DFR) -+#define READ_Y ( ADS_A2A1A0_d_y | ADS_12_BIT | ADS_DFR) -+#define READ_Z1 ( ADS_A2A1A0_d_z1 | ADS_12_BIT | ADS_DFR) -+#define READ_Z2 ( ADS_A2A1A0_d_z2 | ADS_12_BIT | ADS_DFR) -+ -+static int -+read_val(struct ads7846 *ts, unsigned long cmd) -+{ -+ unsigned long data = 0; -+ int repeat = 5; -+ int i; -+ -+ ads_dbg(0, 1, "Queuing data: 0x%08lx\n", cmd << 16); -+ -+ for (i = 0; i < repeat; i++) -+ { -+ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskTFNF)); -+ REG32(ts->regs + SSP_REG_DR) = (ADS_START | cmd | ADS_PD10_ALL_ON) << 16; -+ } -+ -+ for (i = 0; i < repeat; i++) -+ { -+ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskRFVE)); -+ data = (REG32(ts->regs + SSP_REG_DR) >> 3) & 0xFFF; -+ } -+ -+ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskTFNF)); -+ REG32(ts->regs + SSP_REG_DR) = (ADS_START | cmd) << 16; -+ -+ while (!(REG32(ts->regs + SSP_REG_SR) & SSP_SR_mskRFVE)); -+ -+ data = (REG32(ts->regs + SSP_REG_DR) >> 3) & 0xFFF; -+ ads_dbg(0, 1, "CMD <%02lx> data: 0x%08lx( %ld)\n", cmd, data, data); -+ -+ return data; -+} -+ -+static int pendown(struct ads7846 *ts) -+{ -+ return read_val(ts, READ_Z1) > 40; -+} -+ -+static void report(struct ads7846 *ts, struct ts_event *e) -+{ -+ e->x = read_val(ts, READ_X); -+ e->y = read_val(ts, READ_Y); -+ e->z1 = read_val(ts, READ_Z1); -+ e->z2 = read_val(ts, READ_Z2); -+ -+ ads_dbg(debug, 1, "x: %4d, y: %4d, z1: %4d, z2: %4d\n", e->x, e->y, e->z1, e->z2); -+} -+ -+#define FILTER_LIMIT 35 -+ -+static enum hrtimer_restart ads7846_timer(struct hrtimer *handle) -+{ -+ struct ads7846 *ts = container_of(handle, struct ads7846, timer); -+ struct ts_event e; -+ struct irq_desc *desc = (struct irq_desc *)irq_get_irq_data((unsigned int)ts->irq); -+ static int xp = 0, yp = 0; -+ -+ if (ts->disabled) -+ return HRTIMER_NORESTART; -+ -+ if (!pendown(ts)) -+ { -+ ads_dbg(debug, 1, "Release\n"); -+ -+ input_report_key(ts->input, BTN_TOUCH, 0); -+ input_report_abs(ts->input, ABS_PRESSURE, 0); -+ input_sync(ts->input); -+ -+ if(desc->irq_data.chip->irq_ack) -+ desc->irq_data.chip->irq_ack(&desc->irq_data); -+ enable_irq(ts->irq); -+ return HRTIMER_NORESTART; -+ } -+ report(ts, &e); -+ -+#ifdef CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER -+ if (abs(xp - e.x) > FILTER_LIMIT || abs(yp - e.y) > FILTER_LIMIT) -+ { -+#endif -+ input_report_key(ts->input, BTN_TOUCH, 1); -+ input_report_abs(ts->input, ABS_X, e.x); -+ input_report_abs(ts->input, ABS_Y, e.y); -+ input_report_abs(ts->input, ABS_PRESSURE, 50); -+ xp = e.x; -+ yp = e.y; -+#ifdef CONFIG_TOUCHSCREEN_CPE_TS_DEJITTER -+ } -+#endif -+ input_sync(ts->input); -+ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_PERIOD), HRTIMER_MODE_REL); -+ ads_dbg(0, 1, "Leave\n"); -+ return HRTIMER_NORESTART; -+} -+ -+static irqreturn_t ads7846_irq(int irq, void *handle) -+{ -+ struct ads7846 *ts = handle; -+ -+ if (ts->disabled) -+ return IRQ_HANDLED; -+ -+ disable_irq_nosync(irq); -+ hrtimer_start(&ts->timer, ktime_set(0, TS_POLL_DELAY), HRTIMER_MODE_REL); -+ -+ return IRQ_HANDLED; -+} -+ -+static int xspi_init_hw(void __iomem *regs_base) -+{ -+ int rev = REG32(regs_base + SSP_REG_REV); -+ int reva = REG32(regs_base + SSP_REG_REV-0x20); -+ -+ if ((((rev & SSP_REV_mskMAJOR_REV) >> SSP_REV_offMAJOR_REV) != 1)&& -+ (((reva & SSP_REV_mskMAJOR_REV) >> SSP_REV_offMAJOR_REV) != 1)) -+ { -+ ads_dbg(1, 0, "ADS7846 Touchscreen controller initialized failed:\n" -+ "\tcannot detect Faraday SSP Controller\n"); -+ return -ENXIO; -+ } -+ REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offSSPRST); -+ -+ REG32(regs_base + SSP_REG_CR1) = -+ (0UL << SSP_CR1_offPDL) | /* Padding Data Length */ -+ (23UL << SSP_CR1_offSDL) | /* Serial Data Length */ -+ (5UL << SSP_CR1_offSCLKDIV); /* SCLK Divider */ -+ -+ REG32(regs_base + SSP_REG_CR0) = -+ (1UL << SSP_CR0_offFFMT) | /* Frame Format */ -+ (3UL << SSP_CR0_offOPM) | /* Operation Mode */ -+ (0UL << SSP_CR0_offSCLKPO) | /* SCLK Polarity */ -+ (0UL << SSP_CR0_offSCLKPH); /* SCLK Phase */ -+ -+ REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offTXFCLR) | (1UL << SSP_CR2_offRXFCLR); -+ REG32(regs_base + SSP_REG_CR2) |= (1UL << SSP_CR2_offSSPEN) | (1UL << SSP_CR2_offTXDOE); -+ return 0; -+} -+ -+static int ads7846_probe(struct platform_device *pdev) -+{ -+ struct ads7846 *ts = &touchscreen; -+ struct input_dev *input_dev; -+ int err = 0; -+ platform_set_drvdata(pdev, ts); -+ -+ ts->regs = ioremap(0x98b00000, 44); -+ err = xspi_init_hw(ts->regs); -+ if (err) -+ goto err_unmap; -+ input_dev = input_allocate_device(); -+ if (!input_dev) -+ { -+ err = -ENOMEM; -+ goto err_free_mem; -+ } -+ -+ ts->input = input_dev; -+ -+ hrtimer_init(&ts->timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); -+ ts->timer.function = ads7846_timer; -+ -+ input_dev->name = "ADS7846 Touchscreen"; -+ input_dev->phys = ts->phys; -+ -+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS); -+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH); -+ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0); -+ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0); -+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0); -+ -+ ts->irq = TOUCHSCREEN_IRQ; -+ -+ if (request_irq(ts->irq, ads7846_irq, IRQF_TRIGGER_RISING, "touch screen", ts)) -+ goto err_free_mem; -+ -+ err = input_register_device(input_dev); -+ if (err) -+ goto err_free_irq; -+ -+ spin_lock_init(&ts->lock); -+ return 0; -+err_free_irq: -+ free_irq(ts->irq, ts); -+err_free_mem: -+ input_free_device(input_dev); -+err_unmap: -+ iounmap(ts->regs); -+ -+ return err; -+} -+ -+static int __devexit ads7846_remove(struct platform_device *pdev) -+{ -+ struct ads7846 *ts = platform_get_drvdata(pdev); -+ -+ disable_irq(ts->irq); -+ free_irq(ts->irq, ts); -+ iounmap(ts->regs); -+ input_unregister_device(ts->input); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+static int ads7846_suspend( struct platform_device *pdev, pm_message_t message) -+{ -+ struct ads7846 *ts = platform_get_drvdata(pdev); -+ -+ spin_lock_irq(&ts->lock); -+ ts->disabled = true; -+ disable_irq(ts->irq); -+ spin_unlock_irq(&ts->lock); -+ -+ return 0; -+} -+ -+static int ads7846_resume( struct platform_device *pdev) -+{ -+ struct ads7846 *ts = platform_get_drvdata(pdev); -+ -+ spin_lock_irq(&ts->lock); -+ -+ enable_irq(ts->irq); -+ ts->disabled = false; -+ -+ spin_unlock_irq(&ts->lock); -+ -+ return 0; -+} -+#else -+#define ads7846_suspend NULL -+#define ads7846_resume NULL -+#endif -+ -+static void platform_device_release(struct device *dev){ -+} -+ -+static struct resource ads7846_resources[] = -+{ -+ [0] = { -+ .start = SSP_FTSSP010_PA_BASE, -+ .end = SSP_FTSSP010_PA_LIMIT, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = TOUCHSCREEN_IRQ, //feed me! SSP_FTSSP010_IRQ in spec.h -+ .end = TOUCHSCREEN_IRQ, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_device ads7846_device = -+{ -+ .name = "ads7846", -+ .id = -1, -+ .resource = ads7846_resources, -+ .num_resources = ARRAY_SIZE(ads7846_resources), -+ .dev = { -+ .release = platform_device_release, -+ }, -+}; -+ -+#if 0 -+static struct platform_driver ads7846_driver = -+{ -+ .driver = { -+ .name = "ads7846", -+ .owner = THIS_MODULE, -+ }, -+ .probe = ads7846_probe, -+ .remove = __devexit_p(ads7846_remove), -+ .suspend = ads7846_suspend, -+ .resume = ads7846_resume, -+}; -+#else -+static struct platform_driver ads7846_driver = -+{ -+ .driver = { -+ .name = "ads7846", -+ }, -+ .probe = ads7846_probe, -+ .remove = __devexit_p(ads7846_remove), -+ .suspend = ads7846_suspend, -+ .resume = ads7846_resume, -+}; -+#endif -+ -+static int __init ads7846_init(void) -+{ -+ platform_device_register(&ads7846_device); -+ return platform_driver_register(&ads7846_driver); -+} -+ -+static void __exit ads7846_exit(void) -+{ -+ platform_device_unregister(&ads7846_device); -+ platform_driver_unregister(&ads7846_driver); -+} -+ -+module_init(ads7846_init); -+module_exit(ads7846_exit); -+MODULE_DESCRIPTION("ADS7846 TouchScreen Driver"); -+MODULE_LICENSE("GPL"); -diff -Nur linux-3.4.113.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.h linux-3.4.113/drivers/input/touchscreen/cpe_ts/cpe_ts.h ---- linux-3.4.113.orig/drivers/input/touchscreen/cpe_ts/cpe_ts.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/input/touchscreen/cpe_ts/cpe_ts.h 2016-12-01 20:59:24.384613985 +0100 -@@ -0,0 +1,218 @@ -+#ifndef SSP_FARADAY_H -+#define SSP_FARADAY_H -+ -+#define XILINX_SPI_NAME "faraday-spi" -+ -+/* -+ * Register definitions as per "OPB Serial Peripheral Interface ( SPI) ( v1.00e) -+ * Product Specification", DS464 -+ */ -+#define XSPI_CR_OFFSET 0x62 /* 16-bit Control Register */ -+ -+#define XSPI_CR_ENABLE 0x02 -+#define XSPI_CR_MASTER_MODE 0x04 -+#define XSPI_CR_CPOL 0x08 -+#define XSPI_CR_CPHA 0x10 -+#define XSPI_CR_MODE_MASK ( XSPI_CR_CPHA | XSPI_CR_CPOL) -+#define XSPI_CR_TXFIFO_RESET 0x20 -+#define XSPI_CR_RXFIFO_RESET 0x40 -+#define XSPI_CR_MANUAL_SSELECT 0x80 -+#define XSPI_CR_TRANS_INHIBIT 0x100 -+ -+#define XSPI_SR_OFFSET 0x67 /* 8-bit Status Register */ -+ -+#define XSPI_SR_RX_EMPTY_MASK 0x01 /* Receive FIFO is empty */ -+#define XSPI_SR_RX_FULL_MASK 0x02 /* Receive FIFO is full */ -+#define XSPI_SR_TX_EMPTY_MASK 0x04 /* Transmit FIFO is empty */ -+#define XSPI_SR_TX_FULL_MASK 0x08 /* Transmit FIFO is full */ -+#define XSPI_SR_MODE_FAULT_MASK 0x10 /* Mode fault error */ -+ -+#define XSPI_TXD_OFFSET 0x6b /* 8-bit Data Transmit Register */ -+#define XSPI_RXD_OFFSET 0x6f /* 8-bit Data Receive Register */ -+ -+#define XSPI_SSR_OFFSET 0x70 /* 32-bit Slave Select Register */ -+ -+/* Register definitions as per "OPB IPIF ( v3.01c) Product Specification", DS414 -+ * IPIF registers are 32 bit -+ */ -+#define XIPIF_V123B_DGIER_OFFSET 0x1c /* IPIF global int enable reg */ -+#define XIPIF_V123B_GINTR_ENABLE 0x80000000 -+ -+#define XIPIF_V123B_IISR_OFFSET 0x20 /* IPIF interrupt status reg */ -+#define XIPIF_V123B_IIER_OFFSET 0x28 /* IPIF interrupt enable reg */ -+ -+#define XSPI_INTR_MODE_FAULT 0x01 /* Mode fault error */ -+#define XSPI_INTR_SLAVE_MODE_FAULT 0x02 /* Selected as slave while disabled */ -+#define XSPI_INTR_TX_EMPTY 0x04 /* TxFIFO is empty */ -+#define XSPI_INTR_TX_UNDERRUN 0x08 /* TxFIFO was underrun */ -+#define XSPI_INTR_RX_FULL 0x10 /* RxFIFO is full */ -+#define XSPI_INTR_RX_OVERRUN 0x20 /* RxFIFO was overrun */ -+ -+#define XIPIF_V123B_RESETR_OFFSET 0x40 /* IPIF reset register */ -+#define XIPIF_V123B_RESET_MASK 0x0a /* the value to write */ -+ -+/*************************************************************************/ -+#if 0 -+#define SSP_REG_CR0 ( SSP_FTSSP010_VA_BASE + 0x00) /* SSP Control Register 0 */ -+#define SSP_REG_CR1 ( SSP_FTSSP010_VA_BASE + 0x04) /* SSP Control Register 1 */ -+#define SSP_REG_CR2 ( SSP_FTSSP010_VA_BASE + 0x08) /* SSP Control Register 2 */ -+#define SSP_REG_SR ( SSP_FTSSP010_VA_BASE + 0x0c) /* SSP Status Register */ -+#define SSP_REG_ICR ( SSP_FTSSP010_VA_BASE + 0x10) /* SSP Interrupt Control Register */ -+#define SSP_REG_ISR ( SSP_FTSSP010_VA_BASE + 0x14) /* SSP Interrupt Status Register */ -+#define SSP_REG_DR ( SSP_FTSSP010_VA_BASE + 0x18) /* SSP Data Register */ -+#define SSP_REG_ACL ( SSP_FTSSP010_VA_BASE + 0x20) /* AC-Link Slot Valid Register */ -+#define SSP_REG_REV ( SSP_FTSSP010_VA_BASE + 0x40) /* SSP Revision Register */ -+#define SSP_REG_FEA ( SSP_FTSSP010_VA_BASE + 0x44) /* SSP Feature Register */ -+#endif -+#define SSP_REG_CR0 0x00 /* SSP Control Register 0 */ -+#define SSP_REG_CR1 0x04 /* SSP Control Register 1 */ -+#define SSP_REG_CR2 0x08 /* SSP Control Register 2 */ -+#define SSP_REG_SR 0x0C /* SSP Status Register */ -+#define SSP_REG_ICR 0x10 /* SSP Interrupt Control Register */ -+#define SSP_REG_ISR 0x14 /* SSP Interrupt Status Register */ -+#define SSP_REG_DR 0x18 /* SSP Data Register */ -+#define SSP_REG_ACL 0x20 /* AC-Link Slot Valid Register */ -+#define SSP_REG_REV 0x60 /* SSP Revision Register */ -+#define SSP_REG_FEA 0x64 /* SSP Feature Register */ -+ -+#define SSP_CR0_offFFMT 12 /* Frame Format */ -+#define SSP_CR0_offFSDIST 8 /* Frame/Sync and Data Distance */ -+#define SSP_CR0_offLBM 7 /* Loopback Mode */ -+#define SSP_CR0_offLSB 6 /* Bit Sequence Indicator */ -+#define SSP_CR0_offFSPO 5 /* Frame/Sync Polarity */ -+#define SSP_CR0_offFSJSFY 4 /* Data Justify */ -+#define SSP_CR0_offOPM 2 /* Operation Mode */ -+#define SSP_CR0_offSCLKPO 1 /* SCLK Polarity */ -+#define SSP_CR0_offSCLKPH 0 /* SCLK Phase */ -+ -+#define SSP_CR0_mskFFMT ( 0x07UL << SSP_CR0_offFFMT) -+#define SSP_CR0_mskFSDIST ( 0x03UL << SSP_CR0_offFSDIST) -+#define SSP_CR0_mskLBM ( 0x01UL << SSP_CR0_offLBM) -+#define SSP_CR0_mskLSB ( 0x01UL << SSP_CR0_offLSB) -+#define SSP_CR0_mskFSPO ( 0x01UL << SSP_CR0_offFSPO) -+#define SSP_CR0_mskFSJSFY ( 0x01UL << SSP_CR0_offFSJSFY) -+#define SSP_CR0_mskOPM ( 0x03UL << SSP_CR0_offOPM) -+#define SSP_CR0_mskSCLKPO ( 0x01UL << SSP_CR0_offSCLKPO) -+#define SSP_CR0_mskSCLKPH ( 0x01UL << SSP_CR0_offSCLKPH) -+ -+#define SSP_CR1_offPDL 24 /* Padding Data Length */ -+#define SSP_CR1_offSDL 16 /* Serial Data Length */ -+#define SSP_CR1_offSCLKDIV 0 /* SCLK Divider */ -+ -+#define SSP_CR1_mskPDL ( 0xFFUL << SSP_CR1_offPDL) -+#define SSP_CR1_mskSDL ( 0x1FUL << SSP_CR1_offSDL) -+#define SSP_CR1_mskSCLKDIV ( 0xFFUL << SSP_CR1_offSCLKDIV) -+ -+#define SSP_CR2_offSSPRST 6 /* SSP Reset */ -+#define SSP_CR2_offACCRST 5 /* AC-Link Cold Reset Enable */ -+#define SSP_CR2_offACWRST 4 /* AC-Link Warm Reset Enable */ -+#define SSP_CR2_offTXFCLR 3 /* Transmit FIFO Clear */ -+#define SSP_CR2_offRXFCLR 2 /* Recieve FIFO clear */ -+#define SSP_CR2_offTXDOE 1 /* Transmit Data Output Enable */ -+#define SSP_CR2_offSSPEN 0 /* The SSP Enable */ -+ -+#define SSP_CR2_mskSSPRST ( 0x01UL << SSP_CR2_offSSPRST) -+#define SSP_CR2_mskACCRST ( 0x01UL << SSP_CR2_offACCRST) -+#define SSP_CR2_mskACWRST ( 0x01UL << SSP_CR2_offACWRST) -+#define SSP_CR2_mskTXFCLR ( 0x01UL << SSP_CR2_offTXFCLR) -+#define SSP_CR2_mskRXFCLR ( 0x01UL << SSP_CR2_offRXFCLR) -+#define SSP_CR2_mskTXDOE ( 0x01UL << SSP_CR2_offTXDOE) -+#define SSP_CR2_mskSSPEN ( 0x01UL << SSP_CR2_offSSPEN) -+ -+#define SSP_SR_offTFVE 12 /* Transmit FIFO Valid Entries */ -+#define SSP_SR_offRFVE 4 /* Recieve FIFO Valid Entries */ -+#define SSP_SR_offBUSY 2 /* Busy Indicator */ -+#define SSP_SR_offTFNF 1 /* Transmit FIFO not full */ -+#define SSP_SR_offRFF 0 /* Recieve FIFO full */ -+ -+#define SSP_SR_mskTFVE ( 0x1FUL << SSP_SR_offTFVE) -+#define SSP_SR_mskRFVE ( 0x1FUL << SSP_SR_offRFVE) -+#define SSP_SR_mskBUSY ( 0x01UL << SSP_SR_offBUSY) -+#define SSP_SR_mskTFNF ( 0x01UL << SSP_SR_offTFNF) -+#define SSP_SR_mskRFF ( 0x01UL << SSP_SR_offRFF) -+ -+#define SSP_ICR_offTFTHOD 12 /* Transmit FIFO Threshold */ -+#define SSP_ICR_offRFTHOD 8 /* Recieve FIFO Threshold */ -+#define SSP_ICR_offAC97FCEN 6 /* AC97 Frame Complete */ -+#define SSP_ICR_offTFDMAEN 5 /* Transmit DMA Request Enable */ -+#define SSP_ICR_offRFDMAEN 4 /* Recieve DMA Request Enable */ -+#define SSP_ICR_offTFTHIEN 3 /* Transmit FIFO Threshold Interrupt */ -+#define SSP_ICR_offRFTHIEN 2 /* Recieve FIFO Threshold Interrupt */ -+#define SSP_ICR_offTFURIEN 1 /* Transmit FIFO Underrun Interrupt Enable */ -+#define SSP_ICR_offRFORIEN 0 /* Recieve FIFO Overrun Interrupt Enable */ -+ -+#define SSP_ICR_mskTFTHOD ( 0x0FUL << SSP_ICR_offTFTHOD) -+#define SSP_ICR_mskRFTHOD ( 0x0FUL << SSP_ICR_offRFTHOD) -+#define SSP_ICR_mskAC97FCEN ( 0x01UL << SSP_ICR_offAC97FCEN) -+#define SSP_ICR_mskTFDMAEN ( 0x01UL << SSP_ICR_offTFDMAEN) -+#define SSP_ICR_mskRFDMAEN ( 0x01UL << SSP_ICR_offRFDMAEN) -+#define SSP_ICR_mskTFTHIEN ( 0x01UL << SSP_ICR_offTFTHIEN) -+#define SSP_ICR_mskRFTHIEN ( 0x01UL << SSP_ICR_offRFTHIEN) -+#define SSP_ICR_mskTFURIEN ( 0x01UL << SSP_ICR_offTFURIEN) -+#define SSP_ICR_mskRFORIEN ( 0x01UL << SSP_ICR_offRFORIEN) -+ -+#define SSP_ISR_offAC97FCI 4 /* AC97 Frame Complete Interrupt */ -+#define SSP_ISR_offTFTHI 3 /* Transmit FIFO Threshold Interrupt */ -+#define SSP_ISR_offRFTHI 2 /* Recieve FIFO Threshold Interrupt */ -+#define SSP_ISR_offTFURI 1 /* Transmit FIFO underrun Interrupt */ -+#define SSP_ISR_offRFORI 0 /* Recieve FIFO Overun Interrupt */ -+ -+#define SSP_ISR_mskAC97FCI ( 0x01UL << SSP_ISR_offAC97FCI) -+#define SSP_ISR_mskTFTHI ( 0x01UL << SSP_ISR_offTFTHI) -+#define SSP_ISR_mskRFTHI ( 0x01UL << SSP_ISR_offRFTHI) -+#define SSP_ISR_mskTFURI ( 0x01UL << SSP_ISR_offTFURI) -+#define SSP_ISR_mskRFORI ( 0x01UL << SSP_ISR_offRFORI) -+ -+#define SSP_ACL_offSLOT1V 14 /* The 1st Slot is Valid */ -+#define SSP_ACL_offSLOT2V 13 /* The 2nd Slot is Valid */ -+#define SSP_ACL_offSLOT3V 12 /* The 3th Slot is Valid */ -+#define SSP_ACL_offSLOT4V 11 /* The 4th Slot is Valid */ -+#define SSP_ACL_offSLOT5V 10 /* The 5th Slot is Valid */ -+#define SSP_ACL_offSLOT6V 9 /* The 6th Slot is Valid */ -+#define SSP_ACL_offSLOT7V 8 /* The 7th Slot is Valid */ -+#define SSP_ACL_offSLOT8V 7 /* The 8th Slot is Valid */ -+#define SSP_ACL_offSLOT9V 6 /* The 9th Slot is Valid */ -+#define SSP_ACL_offSLOT10V 5 /* The 10th Slot is Valid */ -+#define SSP_ACL_offSLOT11V 4 /* The 11th Slot is Valid */ -+#define SSP_ACL_offSLOT12V 3 /* The 12th Slot is Valid */ -+#define SSP_ACL_offCODECID 0 /* Codec ID, which will be shifted out as tag slot */ -+ -+#define SSP_ACL_mskSLOT1V ( 0x01UL << SSP_ACL_offSLOT1V) -+#define SSP_ACL_mskSLOT2V ( 0x01UL << SSP_ACL_offSLOT2V) -+#define SSP_ACL_mskSLOT3V ( 0x01UL << SSP_ACL_offSLOT3V) -+#define SSP_ACL_mskSLOT4V ( 0x01UL << SSP_ACL_offSLOT4V) -+#define SSP_ACL_mskSLOT5V ( 0x01UL << SSP_ACL_offSLOT5V) -+#define SSP_ACL_mskSLOT6V ( 0x01UL << SSP_ACL_offSLOT6V) -+#define SSP_ACL_mskSLOT7V ( 0x01UL << SSP_ACL_offSLOT7V) -+#define SSP_ACL_mskSLOT8V ( 0x01UL << SSP_ACL_offSLOT8V) -+#define SSP_ACL_mskSLOT9V ( 0x01UL << SSP_ACL_offSLOT9V) -+#define SSP_ACL_mskSLOT10V ( 0x01UL << SSP_ACL_offSLOT10V) -+#define SSP_ACL_mskSLOT11V ( 0x01UL << SSP_ACL_offSLOT11V) -+#define SSP_ACL_mskSLOT12V ( 0x01UL << SSP_ACL_offSLOT12V) -+#define SSP_ACL_mskCODECID ( 0x03UL << SSP_ACL_offCODECID) -+ -+#define SSP_REV_offMAJOR_REV 16 /* Major Revision Number */ -+#define SSP_REV_offMINOR_REV 8 /* Minor Revision Number */ -+#define SSP_REV_offREL_REV 0 /* Release Number */ -+ -+#define SSP_REV_mskMAJOR_REV ( 0xFFUL << SSP_REV_offMAJOR_REV) -+#define SSP_REV_mskMINOR_REV ( 0xFFUL << SSP_REV_offMINOR_REV) -+#define SSP_REV_mskREL_REV ( 0xFFUL << SSP_REV_offREL_REV) -+ -+#define SSP_FEA_offSSP_FCFG 27 /* The SSP Functional Configurations */ -+#define SSP_FEA_offSPIMWR_FCFG 26 /* Motorola's SPI and National Semiconductor's Microwire Configurations */ -+#define SSP_FEA_offI2S_FCFG 25 /* Philips's I2S Functional Configurations */ -+#define SSP_FEA_offAC97_FCFG 24 /* Intel's AC-Link Functional Configurations */ -+#define SSP_FEA_offTXFIFO_WIDTH 16 /* Transmit FIFO Size Configurations */ -+#define SSP_FEA_offRXFIFO_WIDTH 8 /* Recieve FIFO Size Configuration */ -+#define SSP_FEA_offFIFO_WIDTH 0 /* Transmit/Recieve FIFO Width */ -+ -+#define SSP_FEA_mskSSP_FCFG ( 0x01UL << SSP_FEA_offSSP_FCFG) -+#define SSP_FEA_mskSPIMWR_FCFG ( 0x01UL << SSP_FEA_offSPIMWR_FCFG) -+#define SSP_FEA_mskI2S_FCFG ( 0x01UL << SSP_FEA_offI2S_FCFG) -+#define SSP_FEA_mskAC97_FCFG ( 0x01UL << SSP_FEA_offAC97_FCFG) -+#define SSP_FEA_mskTXFIFO_WIDTH ( 0xFFUL << SSP_FEA_offTXFIFO_WIDTH) -+#define SSP_FEA_mskRXFIFO_WIDTH ( 0xFFUL << SSP_FEA_offRXFIFO_WIDTH) -+#define SSP_FEA_mskFIFO_WIDTH ( 0xFFUL << SSP_FEA_offFIFO_WIDTH) -+ -+#endif /* SSP_FARADAY */ -diff -Nur linux-3.4.113.orig/drivers/input/touchscreen/cpe_ts/Makefile linux-3.4.113/drivers/input/touchscreen/cpe_ts/Makefile ---- linux-3.4.113.orig/drivers/input/touchscreen/cpe_ts/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/input/touchscreen/cpe_ts/Makefile 2016-12-01 20:59:24.384613985 +0100 -@@ -0,0 +1 @@ -+obj-$(CONFIG_TOUCHSCREEN_CPE_TS) += cpe_ts.o -diff -Nur linux-3.4.113.orig/drivers/input/touchscreen/Kconfig linux-3.4.113/drivers/input/touchscreen/Kconfig ---- linux-3.4.113.orig/drivers/input/touchscreen/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/input/touchscreen/Kconfig 2016-12-01 20:59:24.384613985 +0100 -@@ -86,6 +86,26 @@ - To compile this driver as a module, choose M here: the - module will be called ad7879-spi. - -+config TOUCHSCREEN_CPE_TS -+ tristate "Touchscreen Driver for AG101/XC5" -+ help -+ This driver directly accesses SPI controller to communicate with -+ the ads7846 chip. -+ -+ Once we have a SPI controller driver -+ , we can adopt to the SPI -+ framework that kernel provides. -+ -+config TOUCHSCREEN_CPE_TS_DEJITTER -+ bool "Dejitter Detection" -+ depends on TOUCHSCREEN_CPE_TS -+ default y -+ help -+ Say Y here to enable dejitter detection in AG101/Leopard Touchscreen Driver. -+ -+ If unsure, say y. -+ -+ - config TOUCHSCREEN_ATMEL_MXT - tristate "Atmel mXT I2C Touchscreen" - depends on I2C -diff -Nur linux-3.4.113.orig/drivers/input/touchscreen/Makefile linux-3.4.113/drivers/input/touchscreen/Makefile ---- linux-3.4.113.orig/drivers/input/touchscreen/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/input/touchscreen/Makefile 2016-12-01 20:59:24.384613985 +0100 -@@ -69,3 +69,4 @@ - obj-$(CONFIG_TOUCHSCREEN_WM97XX_ZYLONITE) += zylonite-wm97xx.o - obj-$(CONFIG_TOUCHSCREEN_W90X900) += w90p910_ts.o - obj-$(CONFIG_TOUCHSCREEN_TPS6507X) += tps6507x-ts.o -+obj-$(CONFIG_TOUCHSCREEN_CPE_TS) += cpe_ts/ -diff -Nur linux-3.4.113.orig/drivers/mmc/core/bus.c linux-3.4.113/drivers/mmc/core/bus.c ---- linux-3.4.113.orig/drivers/mmc/core/bus.c 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/mmc/core/bus.c 2016-12-01 20:59:24.384613985 +0100 -@@ -26,7 +26,9 @@ - #include "bus.h" - - #define to_mmc_driver(d) container_of(d, struct mmc_driver, drv) -- -+#ifdef CONFIG_MMC_TEST -+static struct mmc_driver *mmc_test_drv; -+#endif - static ssize_t mmc_type_show(struct device *dev, - struct device_attribute *attr, char *buf) - { -@@ -109,6 +111,11 @@ - struct mmc_driver *drv = to_mmc_driver(dev->driver); - struct mmc_card *card = mmc_dev_to_card(dev); - -+ #ifdef CONFIG_MMC_TEST -+ mmc_test_drv->probe(card); -+ printk("debug mmc_bus_probe\n"); -+ #endif -+ - return drv->probe(card); - } - -@@ -200,6 +207,11 @@ - int mmc_register_driver(struct mmc_driver *drv) - { - drv->drv.bus = &mmc_bus_type; -+ #ifdef CONFIG_MMC_TEST -+ printk("debug defined config_mmc_test in mmc_register_driver\n"); -+ if(!strcmp(drv->drv.name,"mmc_test")) -+ mmc_test_drv = drv; -+ #endif - return driver_register(&drv->drv); - } - -diff -Nur linux-3.4.113.orig/drivers/mmc/host/ftsdc010.c linux-3.4.113/drivers/mmc/host/ftsdc010.c ---- linux-3.4.113.orig/drivers/mmc/host/ftsdc010.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/mmc/host/ftsdc010.c 2016-12-01 20:59:24.388614139 +0100 -@@ -0,0 +1,1586 @@ -+/* drivers/mmc/host/ftsdc010.c -+ * Copyright (C) 2010 Andestech -+ * -+ * 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 -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "ftsdc010.h" -+ -+#define DRIVER_NAME "ftsdc010" -+ -+#define REG_READ(addr) readl((host->base + addr)) -+#define REG_WRITE(data, addr) writel((data), (host->base + addr)) -+ -+#define APB_CLK_IN (AHB_CLK_IN / 2) -+ -+enum dbg_channels { -+ dbg_err = (1 << 0), -+ dbg_debug = (1 << 1), -+ dbg_info = (1 << 2), -+ dbg_irq = (1 << 3), -+ dbg_sg = (1 << 4), -+ dbg_dma = (1 << 5), -+ dbg_pio = (1 << 6), -+ dbg_fail = (1 << 7), -+ dbg_conf = (1 << 8), -+}; -+ -+static struct workqueue_struct *mywq; -+ -+static const int dbgmap_err = dbg_fail; -+static const int dbgmap_info = dbg_info | dbg_conf; -+static const int dbgmap_debug = dbg_err | dbg_debug | dbg_info | dbg_conf; -+#if 1 -+#define dbg(host, channels, args...) \ -+ do { \ -+ if (dbgmap_err & channels) \ -+ dev_err(&host->pdev->dev, args); \ -+ else if (dbgmap_info & channels) \ -+ dev_info(&host->pdev->dev, args); \ -+ else if (dbgmap_debug & channels) \ -+ dev_dbg(&host->pdev->dev, args); \ -+ } while (0) -+#endif -+#if 0 -+#define dbg(host, channels, args...) \ -+ do { \ -+ printk(KERN_INFO "%s: ", "ftsdc");\ -+ printk(args); \ -+ } while(0) -+#endif -+ -+static void finalize_request(struct ftsdc_host *host); -+static void ftsdc_send_request(struct mmc_host *mmc); -+ -+#ifdef CONFIG_MMC_DEBUG -+ -+static void dbg_dumpregs(struct ftsdc_host *host, char *prefix) -+{ -+ u32 con, cmdarg, r0, r1, r2, r3, rcmd, dcon, dtimer, -+ dlen, sta, clr, imask, pcon, ccon, bwidth, scon1, -+ scon2, ssta, fea; -+ -+ con = REG_READ(SDC_CMD_REG); -+ cmdarg = REG_READ(SDC_ARGU_REG); -+ r0 = REG_READ(SDC_RESPONSE0_REG); -+ r1 = REG_READ(SDC_RESPONSE1_REG); -+ r2 = REG_READ(SDC_RESPONSE2_REG); -+ r3 = REG_READ(SDC_RESPONSE3_REG); -+ rcmd = REG_READ(SDC_RSP_CMD_REG); -+ dcon = REG_READ(SDC_DATA_CTRL_REG); -+ dtimer = REG_READ(SDC_DATA_TIMER_REG); -+ dlen = REG_READ(SDC_DATA_LEN_REG); -+ sta = REG_READ(SDC_STATUS_REG); -+ clr = REG_READ(SDC_CLEAR_REG); -+ imask = REG_READ(SDC_INT_MASK_REG); -+ pcon = REG_READ(SDC_POWER_CTRL_REG); -+ ccon = REG_READ(SDC_CLOCK_CTRL_REG); -+ bwidth = REG_READ(SDC_BUS_WIDTH_REG); -+ scon1 = REG_READ(SDC_SDIO_CTRL1_REG); -+ scon2 = REG_READ(SDC_SDIO_CTRL2_REG); -+ ssta = REG_READ(SDC_SDIO_STATUS_REG); -+ fea = REG_READ(SDC_FEATURE_REG); -+ -+ dbg(host, dbg_debug, "%s CON:[%08x] STA:[%08x] INT:[%08x], PWR:[%08x], CLK:[%08x]\n", -+ prefix, con, sta, imask, pcon, ccon); -+ -+ dbg(host, dbg_debug, "%s DCON:[%08x] DTIME:[%08x]" -+ " DLEN:[%08x] DWIDTH:[%08x]\n", -+ prefix, dcon, dtimer, dlen, bwidth); -+ -+ dbg(host, dbg_debug, "%s R0:[%08x] R1:[%08x]" -+ " R2:[%08x] R3:[%08x]\n", -+ prefix, r0, r1, r2, r3); -+ -+ dbg(host, dbg_debug, "%s SCON1:[%08x] SCON2:[%08x]" -+ " SSTA:[%08x] FEA:[%08x]\n", -+ prefix, scon1, scon2, ssta, fea); -+} -+ -+static void prepare_dbgmsg(struct ftsdc_host *host, struct mmc_command *cmd, -+ int stop) -+{ -+ snprintf(host->dbgmsg_cmd, 300, -+ "#%u%s op:%i arg:0x%08x flags:0x08%x retries:%u", -+ host->ccnt, (stop ? " (STOP)" : ""), -+ cmd->opcode, cmd->arg, cmd->flags, cmd->retries); -+ -+ if (cmd->data) { -+ snprintf(host->dbgmsg_dat, 300, -+ "#%u bsize:%u blocks:%u bytes:%u", -+ host->dcnt, cmd->data->blksz, -+ cmd->data->blocks, -+ cmd->data->blocks * cmd->data->blksz); -+ } else { -+ host->dbgmsg_dat[0] = '\0'; -+ } -+} -+ -+static void dbg_dumpcmd(struct ftsdc_host *host, struct mmc_command *cmd, -+ int fail) -+{ -+ unsigned int dbglvl = fail ? dbg_fail : dbg_debug; -+ -+ if (!cmd) -+ return; -+ -+ if (cmd->error == 0) { -+ dbg(host, dbglvl, "CMD[OK] %s R0:0x%08x\n", -+ host->dbgmsg_cmd, cmd->resp[0]); -+ } else { -+ dbg(host, dbglvl, "CMD[ERR %i] %s Status:%s\n", -+ cmd->error, host->dbgmsg_cmd, host->status); -+ } -+ -+ if (!cmd->data) -+ return; -+ -+ if (cmd->data->error == 0) { -+ dbg(host, dbglvl, "DAT[OK] %s\n", host->dbgmsg_dat); -+ } else { -+ dbg(host, dbglvl, "DAT[ERR %i] %s DCNT:0x%08x\n", -+ cmd->data->error, host->dbgmsg_dat, -+ REG_READ(SDC_DATA_LEN_REG)); -+ } -+} -+#else -+static void dbg_dumpcmd(struct ftsdc_host *host, -+ struct mmc_command *cmd, int fail) { } -+ -+static void prepare_dbgmsg(struct ftsdc_host *host, struct mmc_command *cmd, -+ int stop) { } -+ -+static void dbg_dumpregs(struct ftsdc_host *host, char *prefix) { } -+ -+#endif /* CONFIG_MMC_DEBUG */ -+ -+static inline bool ftsdc_dmaexist(struct ftsdc_host *host) -+{ -+ return (host->dma_req != NULL); -+} -+ -+static inline u32 enable_imask(struct ftsdc_host *host, u32 imask) -+{ -+ u32 newmask; -+ -+#ifdef CONFIG_MMC_DEBUG -+ if (imask & SDC_STATUS_REG_SDIO_INTR) printk("\n*** E ***\n"); -+#endif -+ newmask = REG_READ(SDC_INT_MASK_REG); -+ newmask |= imask; -+ -+ REG_WRITE(newmask, SDC_INT_MASK_REG); -+ -+ return newmask; -+} -+ -+static inline u32 disable_imask(struct ftsdc_host *host, u32 imask) -+{ -+ u32 newmask; -+ -+#ifdef CONFIG_MMC_DEBUG -+ if (imask & SDC_STATUS_REG_SDIO_INTR) printk("\n*** D ***\n"); -+#endif -+ newmask = REG_READ(SDC_INT_MASK_REG); -+ newmask &= ~imask; -+ -+ REG_WRITE(newmask, SDC_INT_MASK_REG); -+ -+ return newmask; -+} -+ -+static inline void clear_imask(struct ftsdc_host *host) -+{ -+ u32 mask = REG_READ(SDC_INT_MASK_REG); -+ -+ /* preserve the SDIO IRQ mask state */ -+ mask &= (SDC_INT_MASK_REG_SDIO_INTR | SDC_INT_MASK_REG_CARD_CHANGE); -+ REG_WRITE(mask, SDC_INT_MASK_REG); -+} -+ -+//static void ftsdc_check_sdio_irq(struct ftsdc_host *host) -+//{ -+// if (host->sdio_irqen) { -+// u32 con = REG_READ(SDC_STATUS_REG); -+// if (con & SDC_STATUS_REG_SDIO_INTR) { -+// printk(KERN_DEBUG "%s: signalling irq\n", __func__); -+// mmc_signal_sdio_irq(host->mmc); -+// } -+// } -+//} -+ -+static inline void get_data_buffer(struct ftsdc_host *host) -+{ -+ struct scatterlist *sg; -+ -+ BUG_ON(host->buf_sgptr >= host->mrq->data->sg_len); -+ -+ sg = &host->mrq->data->sg[host->buf_sgptr]; -+ -+ host->buf_bytes = sg->length; -+ host->buf_ptr = host->dodma ? (u32 *)sg->dma_address : sg_virt(sg); -+ host->buf_sgptr++; -+} -+ -+static inline u32 cal_blksz(unsigned int blksz) -+{ -+ u32 blksztwo = 0; -+ -+ while (blksz >>= 1) -+ blksztwo++; -+ -+ return blksztwo; -+} -+ -+/** -+ * ftsdc_enable_irq - enable IRQ, after having disabled it. -+ * @host: The device state. -+ * @more: True if more IRQs are expected from transfer. -+ * -+ * Enable the main IRQ if needed after it has been disabled. -+ * -+ * The IRQ can be one of the following states: -+ * - enable after data read/write -+ * - disable when handle data read/write -+ */ -+static void ftsdc_enable_irq(struct ftsdc_host *host, bool enable) -+{ -+ unsigned long flags; -+ local_irq_save(flags); -+ -+ host->irq_enabled = enable; -+ -+ if (enable) -+ enable_irq(host->irq); -+ else -+ disable_irq(host->irq); -+ -+ local_irq_restore(flags); -+} -+ -+static void do_pio_read(struct ftsdc_host *host) -+{ -+ u32 fifo; -+ u32 fifo_words; -+ u32 *ptr; -+ u32 status; -+ u32 retry = 0; -+ -+ -+ BUG_ON(host->buf_bytes != 0); -+ -+ while (host->buf_sgptr < host->mrq->data->sg_len) { -+ get_data_buffer(host); -+ -+ dbg(host, dbg_pio, -+ "pio_read(): new target: [%i]@[%p]\n", -+ host->buf_bytes, host->buf_ptr); -+ -+ while (host->buf_bytes) { -+ status = REG_READ(SDC_STATUS_REG); -+ -+ if (status & SDC_STATUS_REG_FIFO_OVERRUN) { -+ fifo = host->fifo_len > host->buf_bytes ? -+ host->buf_bytes : host->fifo_len; -+ -+#if 1 -+ dbg(host, dbg_pio, -+ "pio_read(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", -+ fifo, host->buf_bytes, -+ REG_READ(SDC_DATA_LEN_REG)); -+#endif -+ -+ host->buf_bytes -= fifo; -+ host->buf_count += fifo; -+ -+ fifo_words = fifo >> 2; -+ ptr = host->buf_ptr; -+ while (fifo_words--) -+ *ptr++ = REG_READ(SDC_DATA_WINDOW_REG); -+ -+ host->buf_ptr = ptr; -+ //ADD by river 2010.10.26 for adding some delays for SD card to put data into FIFO again -+ //mdelay(1); -+ udelay(800); -+ //End ADD by river 2010.10.26 for adding some delays for SD card to put data into FIFO again -+ -+ /* sdio allow non-power-of-2 blksz */ -+ if (fifo & 3) { -+ u32 n = fifo & 3; -+ u32 data = REG_READ(SDC_DATA_WINDOW_REG); -+ u8 *p = (u8 *)host->buf_ptr; -+ -+ while (n--) { -+ *p++ = data; -+ data >>= 8; -+ } -+ } -+ } else { -+ udelay(1); -+ if (++retry >= SDC_PIO_RETRY) { -+ host->mrq->data->error = -EIO; -+ goto err; -+ } -+ } -+ } -+ } -+ -+err: -+ -+ host->buf_active = XFER_NONE; -+ host->complete_what = COMPLETION_FINALIZE; -+} -+ -+static void do_pio_write(struct ftsdc_host *host) -+{ -+ u32 fifo; -+ u32 *ptr; -+ u32 status; -+ u32 retry = 0; -+ -+ BUG_ON(host->buf_bytes != 0); -+ -+ while (host->buf_sgptr < host->mrq->data->sg_len) { -+ get_data_buffer(host); -+ -+ dbg(host, dbg_pio, -+ "pio_write(): new source: [%i]@[%p]\n", -+ host->buf_bytes, host->buf_ptr); -+ -+ while (host->buf_bytes) { -+ status = REG_READ(SDC_STATUS_REG); -+ if (status & SDC_STATUS_REG_FIFO_UNDERRUN) { -+ fifo = host->fifo_len > host->buf_bytes ? -+ host->buf_bytes : host->fifo_len; -+ -+ dbg(host, dbg_pio, -+ "pio_write(): fifo:[%02i] buffer:[%03i] dcnt:[%08X]\n", -+ fifo, host->buf_bytes, -+ REG_READ(SDC_DATA_LEN_REG)); -+ -+ host->buf_bytes -= fifo; -+ host->buf_count += fifo; -+ -+ fifo = (fifo + 3) >> 2; -+ ptr = host->buf_ptr; -+ while (fifo--) { -+ REG_WRITE(*ptr, SDC_DATA_WINDOW_REG); -+ ptr++; -+ } -+ host->buf_ptr = ptr; -+ } else { -+ udelay(1); -+ if (++retry >= SDC_PIO_RETRY) { -+ host->mrq->data->error = -EIO; -+ goto err; -+ } -+ } -+ } -+ } -+ -+err: -+ host->buf_active = XFER_NONE; -+ host->complete_what = COMPLETION_FINALIZE; -+} -+ -+static void do_dma_access(struct ftsdc_host *host) -+{ -+ int res; -+ unsigned long timeout; -+ dmad_chreq *req = host->dma_req; -+ dmad_drb *drb = 0; -+ -+ while (host->buf_sgptr < host->mrq->data->sg_len) { -+ -+ INIT_COMPLETION(host->dma_complete); -+ get_data_buffer(host); -+ -+ dbg(host, dbg_dma, -+ "dma_%s(): new target: [%i]@[%p]\n", -+ host->buf_active == XFER_READ ? "read" : "write", -+ host->buf_bytes, host->buf_ptr); -+ -+ res = dmad_alloc_drb(req, &drb); -+ if (res != 0 || (drb == 0)) { -+ dbg(host, dbg_err, "%s() Failed to allocate dma request block!\n", __func__); -+ host->mrq->data->error = -ENODEV; -+ goto err; -+ } -+ -+ drb->addr0 = SDC_FTSDC010_0_PA_BASE + SDC_DATA_WINDOW_REG; -+ drb->addr1 = (dma_addr_t)host->buf_ptr; -+ drb->req_cycle = dmad_bytes_to_cycles(req, host->buf_bytes); -+ drb->sync = &host->dma_complete; -+ -+ timeout = SDC_TIMEOUT_BASE*((host->buf_bytes+511)>>9); -+ -+ res = dmad_submit_request(req, drb, 1); -+ if (res != 0) { -+ dbg(host, dbg_err, "%s() Failed to submit dma request block!\n", __func__); -+ host->mrq->data->error = -ENODEV; -+ goto err; -+ } -+ -+ dbg(host, dbg_err, "reach here!\n"); -+ if (wait_for_completion_timeout(&host->dma_complete, timeout) == 0) { -+ dbg(host, dbg_err, "%s: read timeout\n", __func__); -+ host->mrq->data->error = -ETIMEDOUT; -+ goto err; -+ } -+ } -+ -+ host->dma_finish = true; -+err: -+ host->buf_active = XFER_NONE; -+ host->complete_what = COMPLETION_FINALIZE; -+} -+ -+static void ftsdc_work(struct work_struct *work) -+{ -+ struct ftsdc_host *host = -+ container_of(work, struct ftsdc_host, work); -+ -+ ftsdc_enable_irq(host, false); -+ -+ if (host->dodma) { -+ do_dma_access(host); -+ } else { -+ if (host->buf_active == XFER_WRITE) -+ do_pio_write(host); -+ -+ if (host->buf_active == XFER_READ) -+ do_pio_read(host); -+ } -+ -+ tasklet_schedule(&host->pio_tasklet); -+ ftsdc_enable_irq(host, true); -+} -+ -+ -+static void pio_tasklet(unsigned long data) -+{ -+ struct ftsdc_host *host = (struct ftsdc_host *) data; -+ -+ if (host->complete_what == COMPLETION_XFER_PROGRESS) { -+ queue_work(mywq, (struct work_struct *)&host->work); -+ return; -+ } -+ -+ if (host->complete_what == COMPLETION_FINALIZE) { -+ clear_imask(host); -+ if (host->buf_active != XFER_NONE) { -+ dbg(host, dbg_err, "unfinished %s " -+ "- buf_count:[%u] buf_bytes:[%u]\n", -+ (host->buf_active == XFER_READ) ? "read" : "write", -+ host->buf_count, host->buf_bytes); -+ -+ if (host->mrq->data) -+ host->mrq->data->error = -EINVAL; -+ } -+ -+ finalize_request(host); -+ } -+} -+ -+ -+static void finalize_request(struct ftsdc_host *host) -+{ -+ struct mmc_request *mrq = host->mrq; -+ struct mmc_command *cmd; -+ u32 con; -+ int debug_as_failure = 0; -+ -+ if (host->complete_what != COMPLETION_FINALIZE) -+ return; -+ -+ if (!mrq) -+ return; -+ -+ cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; -+ -+ if (cmd->data && (cmd->error == 0) && -+ (cmd->data->error == 0)) { -+ if (host->dodma && (!host->dma_finish)) { -+ dbg(host, dbg_dma, "DMA Missing (%d)!\n", -+ host->dma_finish); -+ return; -+ } -+ host->dodma = false; -+ } -+ -+ /* Read response from controller. */ -+ if (cmd->flags & MMC_RSP_136) { -+ cmd->resp[3] = REG_READ(SDC_RESPONSE0_REG); -+ cmd->resp[2] = REG_READ(SDC_RESPONSE1_REG); -+ cmd->resp[1] = REG_READ(SDC_RESPONSE2_REG); -+ cmd->resp[0] = REG_READ(SDC_RESPONSE3_REG); -+ } else if (cmd->flags & MMC_RSP_PRESENT) { -+ cmd->resp[0] = REG_READ(SDC_RESPONSE0_REG); -+ } -+ -+ if (cmd->error) -+ debug_as_failure = 1; -+ -+ if (cmd->data && cmd->data->error) -+ debug_as_failure = 1; -+ -+ dbg_dumpcmd(host, cmd, debug_as_failure); -+ -+ clear_imask(host); -+ con = REG_READ(SDC_STATUS_REG); -+ con &= ~SDC_CLEAR_REG_SDIO_INTR; -+ REG_WRITE(con, SDC_CLEAR_REG); -+ -+ if (cmd->data && cmd->error) -+ cmd->data->error = cmd->error; -+ -+ if (cmd->data && cmd->data->stop && (!host->cmd_is_stop)) { -+ host->cmd_is_stop = 1; -+ ftsdc_send_request(host->mmc); -+ return; -+ } -+ -+ /* If we have no data transfer we are finished here */ -+ if (!mrq->data) -+ goto request_done; -+ -+ /* Calulate the amout of bytes transfer if there was no error */ -+ if (mrq->data->error == 0) { -+ mrq->data->bytes_xfered = -+ (mrq->data->blocks * mrq->data->blksz); -+ } else { -+ mrq->data->bytes_xfered = 0; -+ } -+ -+request_done: -+ host->complete_what = COMPLETION_NONE; -+ host->mrq = NULL; -+ -+ host->last_opcode = mrq->cmd->opcode; -+ mmc_request_done(host->mmc, mrq); -+} -+ -+static void ftsdc_send_command(struct ftsdc_host *host, -+ struct mmc_command *cmd) -+{ -+ u32 ccon = 0; -+ u32 newmask = 0; -+ u32 scon; -+ -+ if (cmd->data) { -+ host->complete_what = COMPLETION_XFER_PROGRESS; -+ newmask |= SDC_INT_MASK_REG_RSP_TIMEOUT; -+ } else if (cmd->flags & MMC_RSP_PRESENT) { -+ host->complete_what = COMPLETION_RSPFIN; -+ newmask |= SDC_INT_MASK_REG_RSP_TIMEOUT; -+ } else { -+ host->complete_what = COMPLETION_CMDSENT; -+ newmask |= SDC_INT_MASK_REG_CMD_SEND; -+ } -+ -+ ccon |= cmd->opcode & SDC_CMD_REG_INDEX; -+ ccon |= SDC_CMD_REG_CMD_EN; -+ -+ if (cmd->flags & MMC_RSP_PRESENT) { -+ ccon |= SDC_CMD_REG_NEED_RSP; -+ newmask |= SDC_INT_MASK_REG_RSP_CRC_OK | -+ SDC_INT_MASK_REG_RSP_CRC_FAIL; -+ } -+ -+ if (cmd->flags & MMC_RSP_136) -+ ccon |= SDC_CMD_REG_LONG_RSP; -+ -+ /* applicatiion specific cmd must follow an MMC_APP_CMD. The -+ * value will be updated in finalize_request function */ -+ if (host->last_opcode == MMC_APP_CMD) -+ ccon |= SDC_CMD_REG_APP_CMD; -+ -+ enable_imask(host, newmask); -+ REG_WRITE(cmd->arg, SDC_ARGU_REG); -+ -+ scon = REG_READ(SDC_SDIO_CTRL1_REG); -+ if (host->mmc->card != NULL && mmc_card_sdio(host->mmc->card)) -+ scon |= SDC_SDIO_CTRL1_REG_SDIO_ENABLE; -+ else -+ scon &= ~SDC_SDIO_CTRL1_REG_SDIO_ENABLE; -+ REG_WRITE(scon, SDC_SDIO_CTRL1_REG); -+ -+ dbg_dumpregs(host, ""); -+ dbg(host, dbg_debug, "CON[%x]\n", ccon); -+ -+ REG_WRITE(ccon, SDC_CMD_REG); -+} -+ -+static int ftsdc_setup_data(struct ftsdc_host *host, struct mmc_data *data) -+{ -+ u32 dcon, newmask = 0; -+ -+ /* configure data transfer paramter */ -+ -+ if (!data) -+ return 0; -+ if(host->mmc->card && host->mmc->card->type==(unsigned int)MMC_TYPE_SD){ -+ if (((data->blksz - 1) & data->blksz) != 0) { -+ pr_warning("%s: can't do non-power-of 2 sized block transfers (blksz %d)\n", __func__, data->blksz); -+ return -EINVAL; -+ } -+ } -+ -+ if (data->blksz <= 2) { -+ /* We cannot deal with unaligned blocks with more than -+ * one block being transfered. */ -+ -+ if (data->blocks > 1) { -+ pr_warning("%s: can't do non-word sized block transfers (blksz %d)\n", __func__, data->blksz); -+ return -EINVAL; -+ } -+ } -+ -+ /* data length */ -+ dcon = data->blksz * data->blocks; -+ REG_WRITE(dcon, SDC_DATA_LEN_REG); -+ -+ /* write data control */ -+ dcon = 0; -+ dcon = cal_blksz(data->blksz); -+ -+ /* enable UNDERFUN will trigger interrupt immediatedly -+ * So setup it when rsp is received successfully -+ */ -+ if (data->flags & MMC_DATA_WRITE) { -+ dcon |= SDC_DATA_CTRL_REG_DATA_WRITE; -+ } else { -+ dcon &= ~SDC_DATA_CTRL_REG_DATA_WRITE; -+ newmask |= SDC_INT_MASK_REG_FIFO_OVERRUN; -+ } -+ -+ /* always reset fifo since last transfer may fail */ -+ dcon |= SDC_DATA_CTRL_REG_FIFO_RST; -+ -+ /* enable data transfer which will be pended until cmd is send */ -+ dcon |= SDC_DATA_CTRL_REG_DATA_EN; -+ -+ if (ftsdc_dmaexist(host) && -+ ((data->blksz * data->blocks) & 0xf) == 0) { -+ newmask &= ~SDC_INT_MASK_REG_FIFO_OVERRUN; -+ dcon |= SDC_DATA_CTRL_REG_DMA_EN; -+ dcon |= SDC_DMA_TYPE_4; -+ host->dodma = true; -+ -+ } -+ -+ REG_WRITE(dcon, SDC_DATA_CTRL_REG); -+ -+ /* add to IMASK register */ -+ newmask |= SDC_INT_MASK_REG_DATA_CRC_FAIL | -+ SDC_INT_MASK_REG_DATA_TIMEOUT; -+ -+ enable_imask(host, newmask); -+ -+ /* handle sdio */ -+ dcon = SDC_SDIO_CTRL1_REG_READ_WAIT_ENABLE & REG_READ(SDC_SDIO_CTRL1_REG); -+ dcon |= data->blksz | data->blocks << 15; -+ if (1 < data->blocks) -+ dcon |= SDC_SDIO_CTRL1_REG_SDIO_BLK_MODE; -+ REG_WRITE(dcon, SDC_SDIO_CTRL1_REG); -+ -+ return 0; -+} -+ -+#define BOTH_DIR (MMC_DATA_WRITE | MMC_DATA_READ) -+ -+static int ftsdc_prepare_buffer(struct ftsdc_host *host, struct mmc_data *data) -+{ -+ int rw = (data->flags & MMC_DATA_WRITE) ? 1 : 0; -+ -+ if ((!host->mrq) || (!host->mrq->data)) -+ return -EINVAL; -+ -+ BUG_ON((data->flags & BOTH_DIR) == BOTH_DIR); -+ -+ host->buf_sgptr = 0; -+ host->buf_bytes = 0; -+ host->buf_count = 0; -+ host->buf_active = rw ? XFER_WRITE : XFER_READ; -+ -+ if (host->dodma) { -+ u32 dma_len; -+ u32 drb_size; -+ dma_len = dma_map_sg(mmc_dev(host->mmc), data->sg, data->sg_len, -+ rw ? DMA_TO_DEVICE : DMA_FROM_DEVICE); -+ if (dma_len == 0) -+ return -ENOMEM; -+ -+ -+ dmad_config_channel_dir(host->dma_req, -+ rw ? DMAD_DIR_A1_TO_A0 : DMAD_DIR_A0_TO_A1); -+ -+ drb_size = dmad_max_size_per_drb(host->dma_req); -+ if (drb_size < (data->blksz & data->blocks)) -+ return -ENODEV; -+ -+ host->dma_finish = false; -+ } -+ -+ return 0; -+} -+ -+static irqreturn_t ftsdc_irq(int irq, void *dev_id) -+{ -+ struct ftsdc_host *host = dev_id; -+ struct mmc_command *cmd; -+ u32 mci_status; -+ u32 mci_clear; -+ u32 mci_imsk; -+ unsigned long iflags; -+ -+ mci_status = REG_READ(SDC_STATUS_REG); -+ mci_imsk = REG_READ(SDC_INT_MASK_REG); -+ -+ dbg(host, dbg_debug, "irq: status:0x%08x, mask : %08x\n", mci_status, mci_imsk); -+ -+ if (mci_status & SDC_STATUS_REG_SDIO_INTR) { -+ if (mci_imsk & SDC_INT_MASK_REG_SDIO_INTR) { -+ mci_clear = SDC_CLEAR_REG_SDIO_INTR; -+ REG_WRITE(mci_clear, SDC_CLEAR_REG); -+ -+ mmc_signal_sdio_irq(host->mmc); -+ return IRQ_HANDLED; -+ } -+ } -+ -+ spin_lock_irqsave(&host->complete_lock, iflags); -+ -+ mci_status = REG_READ(SDC_STATUS_REG); -+ mci_clear = 0; -+ -+ if (mci_status & SDC_STATUS_REG_CARD_CHANGE) { -+ if ((mci_status & SDC_STATUS_REG_CARD_DETECT) -+ == SDC_CARD_INSERT) { -+ host->status = "card insert"; -+ mmc_detect_change(host->mmc, msecs_to_jiffies(500)); -+ } else { -+ host->status = "card remove"; -+ } -+ -+ mci_clear |= SDC_CLEAR_REG_CARD_CHANGE; -+ dbg(host, dbg_irq, "%s\n", host->status); -+ -+ if (host->complete_what != COMPLETION_NONE) { -+ host->mrq->cmd->error = -EIO; -+ goto close_transfer; -+ } -+ -+ goto irq_out; -+ } -+ -+ if ((host->complete_what == COMPLETION_NONE) || -+ (host->complete_what == COMPLETION_FINALIZE)) { -+ host->status = "nothing to complete"; -+ mci_clear = -1u; -+ goto irq_out; -+ } -+ -+ if (!host->mrq) { -+ host->status = "no active mrq"; -+ clear_imask(host); -+ goto irq_out; -+ } -+ -+ cmd = host->cmd_is_stop ? host->mrq->stop : host->mrq->cmd; -+ -+ if (!cmd) { -+ host->status = "no active cmd"; -+ clear_imask(host); -+ goto irq_out; -+ } -+ -+ if (mci_status & SDC_STATUS_REG_CMD_SEND) { -+ mci_clear |= SDC_CLEAR_REG_CMD_SEND; -+ -+ if (host->complete_what == COMPLETION_CMDSENT) { -+ host->status = "ok: command sent"; -+ goto close_transfer; -+ } else { -+ host->status = "error: command sent(status not match)"; -+ cmd->error = -EINVAL; -+ goto fail_transfer; -+ } -+ } -+ -+ /* handle error status */ -+ if (mci_status & SDC_STATUS_REG_RSP_TIMEOUT) { -+ dbg(host, dbg_err, "CMDSTAT: error RSP TIMEOUT\n"); -+ mci_clear |= SDC_CLEAR_REG_RSP_TIMEOUT; -+ cmd->error = -ETIMEDOUT; -+ host->status = "error: response timeout"; -+ goto fail_transfer; -+ } -+ -+ if (mci_status & SDC_STATUS_REG_RSP_CRC_FAIL) { -+ mci_clear |= SDC_CLEAR_REG_RSP_CRC_FAIL; -+ /* This is wierd hack */ -+ if (cmd->flags & MMC_RSP_CRC) { -+ dbg(host, dbg_err, "CMDSTAT: error RSP CRC\n"); -+ cmd->error = -EILSEQ; -+ host->status = "error: RSP CRC failed"; -+ goto fail_transfer; -+ } else { -+ host->status = "R3 or R4 type command"; -+ goto close_transfer; -+ } -+ } -+ -+ if (mci_status & SDC_STATUS_REG_RSP_CRC_OK) { -+ mci_clear |= SDC_CLEAR_REG_RSP_CRC_OK; -+ -+ if (host->complete_what == COMPLETION_XFER_PROGRESS) { -+ REG_WRITE(mci_clear, SDC_CLEAR_REG); -+ -+ host->status = "RSP recv OK"; -+ if (!cmd->data) -+ goto close_transfer; -+ -+ if (host->dodma) { -+ tasklet_schedule(&host->pio_tasklet); -+ host->status = "dma access"; -+ goto irq_out; -+ } -+ -+ if (host->buf_active == XFER_WRITE) -+ enable_imask(host, SDC_INT_MASK_REG_FIFO_UNDERRUN); -+ } else if (host->complete_what == COMPLETION_RSPFIN) { -+ goto close_transfer; -+ } -+ } -+ -+ /* handler data transfer */ -+ if (mci_status & SDC_STATUS_REG_DATA_TIMEOUT) { -+ dbg(host, dbg_err, "CMDSTAT: error DATA TIMEOUT\n"); -+ mci_clear |= SDC_CLEAR_REG_DATA_TIMEOUT; -+ cmd->error = -ETIMEDOUT; -+ host->status = "error: data timeout"; -+ goto fail_transfer; -+ } -+ -+ if (mci_status & SDC_STATUS_REG_DATA_CRC_FAIL) { -+ dbg(host, dbg_err, "CMDSTAT: error DATA CRC\n"); -+ mci_clear |= SDC_CLEAR_REG_DATA_CRC_FAIL; -+ cmd->error = -EILSEQ; -+ host->status = "error: data CRC fail"; -+ goto fail_transfer; -+ } -+ -+ if ((mci_status & SDC_STATUS_REG_FIFO_UNDERRUN) || -+ mci_status & SDC_STATUS_REG_FIFO_OVERRUN) { -+ -+ disable_imask(host, SDC_INT_MASK_REG_FIFO_OVERRUN | -+ SDC_INT_MASK_REG_FIFO_UNDERRUN); -+ -+ if (!host->dodma) { -+ if (host->buf_active == XFER_WRITE) { -+ tasklet_schedule(&host->pio_tasklet); -+ host->status = "pio tx"; -+ } else if (host->buf_active == XFER_READ) { -+ -+ tasklet_schedule(&host->pio_tasklet); -+ host->status = "pio rx"; -+ } -+ } -+ } -+ -+ goto irq_out; -+ -+fail_transfer: -+ host->buf_active = XFER_NONE; -+ -+close_transfer: -+ host->complete_what = COMPLETION_FINALIZE; -+ -+ clear_imask(host); -+ tasklet_schedule(&host->pio_tasklet); -+ -+irq_out: -+ REG_WRITE(mci_clear, SDC_CLEAR_REG); -+ -+ dbg(host, dbg_debug, "irq: %s\n", host->status); -+ spin_unlock_irqrestore(&host->complete_lock, iflags); -+ return IRQ_HANDLED; -+} -+ -+static void ftsdc_send_request(struct mmc_host *mmc) -+{ -+ struct ftsdc_host *host = mmc_priv(mmc); -+ struct mmc_request *mrq = host->mrq; -+ struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd; -+ -+ host->ccnt++; -+ prepare_dbgmsg(host, cmd, host->cmd_is_stop); -+ dbg(host, dbg_debug, "%s\n", host->dbgmsg_cmd); -+ -+ if (cmd->data) { -+ int res = ftsdc_setup_data(host, cmd->data); -+ -+ host->dcnt++; -+ -+ if (res) { -+ dbg(host, dbg_err, "setup data error %d\n", res); -+ cmd->error = res; -+ cmd->data->error = res; -+ -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ -+ res = ftsdc_prepare_buffer(host, cmd->data); -+ -+ if (res) { -+ dbg(host, dbg_err, "data prepare error %d\n", res); -+ cmd->error = res; -+ cmd->data->error = res; -+ -+ mmc_request_done(mmc, mrq); -+ return; -+ } -+ } -+ -+ /* Send command */ -+ ftsdc_send_command(host, cmd); -+} -+ -+static int ftsdc_get_cd(struct mmc_host *mmc) -+{ -+ struct ftsdc_host *host = mmc_priv(mmc); -+ -+ u32 con = REG_READ(SDC_STATUS_REG); -+ dbg(host, dbg_debug, "get_cd status:%.8x\n\n", con); -+ -+ return (con & SDC_STATUS_REG_CARD_DETECT) ? 0 : 1; -+} -+ -+static void ftsdc_request(struct mmc_host *mmc, struct mmc_request *mrq) -+{ -+ struct ftsdc_host *host = mmc_priv(mmc); -+ -+/* work_around_for_amerald(mrq);*/ -+ host->status = "mmc request"; -+ host->cmd_is_stop = 0; -+ host->mrq = mrq; -+ if (ftsdc_get_cd(mmc) == 0) { -+ dbg(host, dbg_err, "%s: no medium present\n", __func__); -+ host->mrq->cmd->error = -ENOMEDIUM; -+ mmc_request_done(mmc, mrq); -+ } else { -+ ftsdc_send_request(mmc); -+ } -+ -+ dbg(host, dbg_debug, "send request \n"); -+} -+ -+static void ftsdc_set_clk(struct ftsdc_host *host, struct mmc_ios *ios) -+{ -+ u32 clk_div = 0; -+ u32 con; -+ -+ dbg(host, dbg_debug, "request clk : %u \n", ios->clock); -+ con = REG_READ(SDC_CLOCK_CTRL_REG); -+ if (ios->clock == 0) { -+ host->real_rate = 0; -+ con |= SDC_CLOCK_CTRL_REG_CLK_DIS; -+ } else { -+ clk_div = (APB_CLK_IN / (ios->clock << 1)) - 1; -+ host->real_rate = APB_CLK_IN / ((clk_div+1)<<1); -+ if (host->real_rate > ios->clock) { -+ ++clk_div; -+ host->real_rate = APB_CLK_IN / ((clk_div+1)<<1); -+ } -+ if (clk_div > 127) -+ dbg(host, dbg_err, "%s: no match clock rate, %u\n", __func__, ios->clock); -+ -+ con = (con & ~SDC_CLOCK_CTRL_REG_CLK_DIV) | (clk_div & SDC_CLOCK_CTRL_REG_CLK_DIV); -+ con &= ~SDC_CLOCK_CTRL_REG_CLK_DIS; -+ } -+ -+ REG_WRITE(con, SDC_CLOCK_CTRL_REG); -+} -+ -+static void ftsdc_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) -+{ -+ struct ftsdc_host *host = mmc_priv(mmc); -+ u32 con; -+ -+ con = REG_READ(SDC_POWER_CTRL_REG); -+ switch (ios->power_mode) { -+ case MMC_POWER_ON: -+ case MMC_POWER_UP: -+ con |= SDC_POWER_CTRL_REG_POWER_ON; -+ break; -+ case MMC_POWER_OFF: -+ default: -+ con &= ~SDC_POWER_CTRL_REG_POWER_ON; -+ break; -+ } -+ -+ REG_WRITE(con, SDC_POWER_CTRL_REG); -+ -+ ftsdc_set_clk(host, ios); -+ -+ if ((ios->power_mode == MMC_POWER_ON) || -+ (ios->power_mode == MMC_POWER_UP)) { -+ dbg(host, dbg_debug, "running at %ukHz (requested: %ukHz).\n", -+ host->real_rate/1000, ios->clock/1000); -+ } else { -+ dbg(host, dbg_debug, "powered down.\n"); -+ } -+ -+ host->bus_width = ios->bus_width; -+ /* write bus configure */ -+ con = REG_READ(SDC_BUS_WIDTH_REG); -+ -+ con &= ~(SDC_BUS_WIDTH_REG_SINGLE_BUS | -+ SDC_BUS_WIDTH_REG_WIDE_4_BUS | -+ SDC_BUS_WIDTH_REG_WIDE_8_BUS); -+ if (host->bus_width == MMC_BUS_WIDTH_1) -+ con |= SDC_BUS_WIDTH_REG_SINGLE_BUS; -+ else if (host->bus_width == MMC_BUS_WIDTH_4) -+ con |= SDC_BUS_WIDTH_REG_WIDE_4_BUS; -+ else if (host->bus_width == MMC_BUS_WIDTH_8) -+ con |= SDC_BUS_WIDTH_REG_WIDE_8_BUS; -+ else { -+ dbg(host, dbg_err, "set_ios: can't support bus mode"); -+ } -+ REG_WRITE(con, SDC_BUS_WIDTH_REG); -+ -+ /*set rsp and data timeout */ -+ con = -1; -+ REG_WRITE(con, SDC_DATA_TIMER_REG); -+} -+ -+static int ftsdc_get_ro(struct mmc_host *mmc) -+{ -+ struct ftsdc_host *host = mmc_priv(mmc); -+ u32 con = REG_READ(SDC_STATUS_REG); -+ dbg(host, dbg_debug, "get_ro status:%.8x\n", con); -+ -+ return (con & SDC_STATUS_REG_CARD_LOCK) ? 1 : 0; -+} -+ -+ -+static void ftsdc_enable_sdio_irq(struct mmc_host *mmc, int enable) -+{ -+ struct ftsdc_host *host = mmc_priv(mmc); -+ unsigned long flags; -+ u32 con; -+#ifdef CONFIG_MMC_DEBUG -+ u32 ena; -+#endif -+ -+ local_irq_save(flags); -+ -+ con = REG_READ(SDC_INT_MASK_REG); -+#ifdef CONFIG_MMC_DEBUG -+ ena = (con & SDC_STATUS_REG_SDIO_INTR) ? 1:0; -+ if (ena == enable) -+ printk("\n*** XXX ***\n"); -+#endif -+ -+ con = enable ? (con | SDC_STATUS_REG_SDIO_INTR) : (con & ~SDC_STATUS_REG_SDIO_INTR); -+ REG_WRITE(con, SDC_INT_MASK_REG); -+ -+#ifdef CONFIG_MMC_DEBUG -+ //check and ensure data out to SD host controller -+ ena = (REG_READ(SDC_INT_MASK_REG) & SDC_STATUS_REG_SDIO_INTR) ? 1:0; -+ if (ena != enable) { -+ printk("\n*** YYY ***\n"); -+ } -+#endif -+ -+ local_irq_restore(flags); -+} -+ -+static struct mmc_host_ops ftsdc_ops = { -+ .request = ftsdc_request, -+ .set_ios = ftsdc_set_ios, -+ .get_ro = ftsdc_get_ro, -+ .get_cd = ftsdc_get_cd, -+ .enable_sdio_irq = ftsdc_enable_sdio_irq, -+}; -+ -+#ifdef CONFIG_DEBUG_FS -+ -+static int ftsdc_state_show(struct seq_file *seq, void *v) -+{ -+ struct ftsdc_host *host = seq->private; -+ -+ seq_printf(seq, "Register base = 0x%08x\n", (u32)host->base); -+ seq_printf(seq, "Clock rate = %u\n", host->real_rate); -+ seq_printf(seq, "host status = %s\n", host->status); -+ seq_printf(seq, "IRQ = %d\n", host->irq); -+ seq_printf(seq, "IRQ enabled = %d\n", host->irq_enabled); -+ seq_printf(seq, "complete what = %d\n", host->complete_what); -+ seq_printf(seq, "dma support = %d\n", ftsdc_dmaexist(host)); -+ seq_printf(seq, "use dma = %d\n", host->dodma); -+ -+ return 0; -+} -+ -+static int ftsdc_state_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, ftsdc_state_show, inode->i_private); -+} -+ -+static const struct file_operations ftsdc_fops_state = { -+ .owner = THIS_MODULE, -+ .open = ftsdc_state_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+#define DBG_REG(_r) { .addr = SDC_## _r ## _REG, .name = #_r } -+ -+struct ftsdc_reg { -+ unsigned short addr; -+ unsigned char *name; -+} debug_regs[] = { -+ DBG_REG(CMD), -+ DBG_REG(ARGU), -+ DBG_REG(RESPONSE0), -+ DBG_REG(RESPONSE1), -+ DBG_REG(RESPONSE2), -+ DBG_REG(RESPONSE3), -+ DBG_REG(RSP_CMD), -+ DBG_REG(DATA_CTRL), -+ DBG_REG(DATA_TIMER), -+ DBG_REG(DATA_LEN), -+ DBG_REG(STATUS), -+ DBG_REG(CLEAR), -+ DBG_REG(INT_MASK), -+ DBG_REG(POWER_CTRL), -+ DBG_REG(CLOCK_CTRL), -+ DBG_REG(BUS_WIDTH), -+ DBG_REG(SDIO_CTRL1), -+ DBG_REG(SDIO_CTRL2), -+ DBG_REG(SDIO_STATUS), -+ DBG_REG(FEATURE), -+ DBG_REG(REVISION), -+ {} -+}; -+ -+static int ftsdc_regs_show(struct seq_file *seq, void *v) -+{ -+ struct ftsdc_host *host = seq->private; -+ struct ftsdc_reg *rptr = debug_regs; -+ -+ for (; rptr->name; rptr++) -+ seq_printf(seq, "SDI%s\t=0x%08x\n", rptr->name, -+ REG_READ(rptr->addr)); -+ -+ return 0; -+} -+ -+static int ftsdc_regs_open(struct inode *inode, struct file *file) -+{ -+ return single_open(file, ftsdc_regs_show, inode->i_private); -+} -+ -+static const struct file_operations ftsdc_fops_regs = { -+ .owner = THIS_MODULE, -+ .open = ftsdc_regs_open, -+ .read = seq_read, -+ .llseek = seq_lseek, -+ .release = single_release, -+}; -+ -+static void ftsdc_debugfs_attach(struct ftsdc_host *host) -+{ -+ struct device *dev = &host->pdev->dev; -+ -+ host->debug_root = debugfs_create_dir(dev_name(dev), NULL); -+ if (IS_ERR(host->debug_root)) { -+ dev_err(dev, "failed to create debugfs root\n"); -+ return; -+ } -+ -+ host->debug_state = debugfs_create_file("state", 0444, -+ host->debug_root, host, -+ &ftsdc_fops_state); -+ -+ if (IS_ERR(host->debug_state)) -+ dev_err(dev, "failed to create debug state file\n"); -+ -+ host->debug_regs = debugfs_create_file("regs", 0444, -+ host->debug_root, host, -+ &ftsdc_fops_regs); -+ -+ if (IS_ERR(host->debug_regs)) -+ dev_err(dev, "failed to create debug regs file\n"); -+} -+ -+static void ftsdc_debugfs_remove(struct ftsdc_host *host) -+{ -+ debugfs_remove(host->debug_regs); -+ debugfs_remove(host->debug_state); -+ debugfs_remove(host->debug_root); -+} -+ -+#else -+static inline void ftsdc_debugfs_attach(struct ftsdc_host *host) { } -+static inline void ftsdc_debugfs_remove(struct ftsdc_host *host) { } -+ -+#endif /* CONFIG_DEBUG_FS */ -+ -+#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) -+static int ftsdc_alloc_dma(struct ftsdc_host *host) -+{ -+ dmad_chreq *req = host->dma_req; -+ -+ req = kzalloc(sizeof(dmad_chreq), GFP_KERNEL); -+#ifdef CONFIG_PLATFORM_APBDMA -+#ifdef CONFIG_PLAT_AG102 -+ //ADD by river 2010.10.20 -+ outl(inl(PCU_VA_BASE + 0x38) | 0x00000300, PCU_VA_BASE + 0x38); -+ //End ADD by river 2010.10.20 -+#endif -+ req->apb_req.addr0_ctrl = APBBR_ADDRINC_FIXED; /* (in) APBBR_ADDRINC_xxx */ -+/* for amerald */ -+ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID){ -+ req->apb_req.addr0_reqn = APBBR_REQN_SDC_AMERALD; -+ }else -+ { -+ req->apb_req.addr0_reqn = APBBR_REQN_SDC; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ -+ } -+ req->apb_req.addr1_ctrl = APBBR_ADDRINC_I4X; /* (in) APBBR_ADDRINC_xxx */ -+ req->apb_req.addr1_reqn = APBBR_REQN_NONE; /* (in) APBBR_REQN_xxx (also used to help determine bus selection) */ -+ req->apb_req.burst_mode = 1; /* (in) Burst mode (0: no burst 1-, 1: burst 4- data cycles per dma cycle) */ -+ req->apb_req.data_width = APBBR_DATAWIDTH_4; /* (in) APBBR_DATAWIDTH_4(word), APBBR_DATAWIDTH_2(half-word), APBBR_DATAWIDTH_1(byte) */ -+ req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ -+ req->controller = DMAD_DMAC_APB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ -+ req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; -+ -+ if (dmad_channel_alloc(req) == 0) { -+ dbg(host, dbg_debug, "%s: APB dma channel allocated (ch: %d)\n", __func__, req->channel); -+ host->dma_req = req; -+ return 0; -+ } -+ -+ memset(req, 0, sizeof(dmad_chreq)); -+ dbg(host, dbg_info, "%s: APB dma channel allocation failed\n", __func__); -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ req->ahb_req.sync = 1; /* (in) non-zero if src and dst have different clock domain */ -+ req->ahb_req.priority = DMAC_CSR_CHPRI_1; /* (in) DMAC_CSR_CHPRI_0 (lowest) ~ DMAC_CSR_CHPRI_3 (highest) */ -+ req->ahb_req.hw_handshake = 1; /* (in) non-zero to enable hardware handshake mode */ -+ req->ahb_req.burst_size = DMAC_CSR_SIZE_4; /* (in) DMAC_CSR_SIZE_1 ~ DMAC_CSR_SIZE_256 */ -+ req->ahb_req.addr0_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ -+ req->ahb_req.addr0_ctrl = DMAC_CSR_AD_FIX; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ -+ req->ahb_req.addr0_reqn = DMAC_REQN_SDC; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ -+ req->ahb_req.addr1_width = DMAC_CSR_WIDTH_32; /* (in) DMAC_CSR_WIDTH_8, DMAC_CSR_WIDTH_16, or DMAC_CSR_WIDTH_32 */ -+ req->ahb_req.addr1_ctrl = DMAC_CSR_AD_INC; /* (in) DMAC_CSR_AD_INC, DMAC_CSR_AD_DEC, or DMAC_CSR_AD_FIX */ -+ req->ahb_req.addr1_reqn = DMAC_REQN_NONE; /* (in) DMAC_REQN_xxx (also used to help determine channel number) */ -+ req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; /* (in) DMAD_DIR_A0_TO_A1, DMAD_DIR_A1_TO_A0 */ -+ -+ req->controller = DMAD_DMAC_AHB_CORE; /* (in) DMAD_DMAC_AHB_CORE, DMAD_DMAC_APB_CORE */ -+ req->flags = DMAD_FLAGS_SLEEP_BLOCK | DMAD_FLAGS_BIDIRECTION; -+ -+ if (dmad_channel_alloc(req) == 0) { -+ dbg(host, dbg_debug, "%s: AHB dma channel allocated (ch: %d)\n", __func__, req->channel); -+ host->dma_req = req; -+ return 0; -+ } -+ -+ dbg(host, dbg_info, "%s: AHB dma channel allocation failed\n", __func__); -+#endif -+ -+ kfree(req); -+ return -ENODEV; -+ -+} -+#endif -+ -+static int __devinit ftsdc_probe(struct platform_device *pdev) -+{ -+ struct ftsdc_host *host; -+ struct mmc_host *mmc; -+ int ret = -ENOMEM; -+ u32 con; -+ -+ mmc = mmc_alloc_host(sizeof(struct ftsdc_host), &pdev->dev); -+ if (!mmc) { -+// ret = -ENOMEM; -+ goto probe_out; -+ } -+ -+ host = mmc_priv(mmc); -+ host->mmc = mmc; -+ host->pdev = pdev; -+ -+ mywq = create_workqueue("atcsdc_queue"); -+ if (NULL == mywq) -+ goto probe_free_host; -+ -+ spin_lock_init(&host->complete_lock); -+ tasklet_init(&host->pio_tasklet, pio_tasklet, (unsigned long) host); -+ init_completion(&host->dma_complete); -+ INIT_WORK(&host->work, ftsdc_work); -+ -+ host->complete_what = COMPLETION_NONE; -+ host->buf_active = XFER_NONE; -+ -+#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) -+ ftsdc_alloc_dma(host); -+#endif -+ -+ host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); -+ if (!host->mem) { -+ dev_err(&pdev->dev, -+ "failed to get io memory region resouce.\n"); -+ -+ ret = -ENOENT; -+ goto probe_free_host; -+ } -+ -+ host->mem = request_mem_region(host->mem->start, -+ resource_size(host->mem), pdev->name); -+ -+ if (!host->mem) { -+ dev_err(&pdev->dev, "failed to request io memory region.\n"); -+ ret = -ENOENT; -+ goto probe_free_wq; -+ } -+ -+ host->base = (void __iomem *) SDC_FTSDC010_0_VA_BASE; -+ host->irq = SDC_FTSDC010_IRQ; -+ if (request_irq(host->irq, ftsdc_irq, IRQF_DISABLED, DRIVER_NAME, host)) { -+ dev_err(&pdev->dev, "failed to request mci interrupt.\n"); -+ ret = -ENOENT; -+ goto probe_free_mem_region; -+ } -+ host->irq_enabled = true; -+ -+ /* enable card change interruption */ -+ con = REG_READ(SDC_INT_MASK_REG); -+ con |= SDC_INT_MASK_REG_CARD_CHANGE; -+ REG_WRITE(con, SDC_INT_MASK_REG); -+ -+ con = REG_READ(SDC_BUS_WIDTH_REG); -+ -+ mmc->ops = &ftsdc_ops; -+ mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; -+ -+ if (con & SDC_WIDE_4_BUS_SUPPORT) -+ mmc->caps |= MMC_CAP_4_BIT_DATA; -+ else if (con & SDC_WIDE_8_BUS_SUPPORT) -+ mmc->caps |= MMC_CAP_8_BIT_DATA; -+ -+#ifndef A320D_BUILDIN_SDC -+ mmc->caps |= MMC_CAP_SDIO_IRQ; -+#endif -+ -+ mmc->f_min = APB_CLK_IN / (2 * 128); -+ mmc->f_max = APB_CLK_IN / 2; -+ -+ /* limit SDIO mode max size */ -+ mmc->max_req_size = 128 * 1024 * 1024 - 1; -+ mmc->max_blk_size = 2047; -+ mmc->max_req_size = (mmc->max_req_size + 1) / (mmc->max_blk_size + 1); -+ mmc->max_seg_size = mmc->max_req_size; -+ mmc->max_blk_count = (1<<17)-1; -+ -+ /* kernel default value. see Doc/block/biodocs.txt */ -+ /* -+ 'struct mmc_host' has no member named 'max_phys_segs' -+ 'struct mmc_host' has no member named 'max_hw_segs' -+ */ -+// mmc->max_phys_segs = 128; -+// mmc->max_hw_segs = 128; -+ -+ /* set fifo lenght and default threshold half */ -+ con = REG_READ(SDC_FEATURE_REG); -+ host->fifo_len = (con & SDC_FEATURE_REG_FIFO_DEPTH) * sizeof(u32); -+ -+ dbg(host, dbg_debug, -+ "probe: mapped mci_base:%p irq:%u.\n", -+ host->base, host->irq); -+ -+ dbg_dumpregs(host, ""); -+ -+ ret = mmc_add_host(mmc); -+ if (ret) { -+ dev_err(&pdev->dev, "failed to add mmc host.\n"); -+ goto probe_free_irq; -+ } -+ -+ ftsdc_debugfs_attach(host); -+ -+ platform_set_drvdata(pdev, mmc); -+ dev_info(&pdev->dev, "%s - using %s SDIO IRQ\n", mmc_hostname(mmc), -+ mmc->caps & MMC_CAP_SDIO_IRQ ? "hw" : "sw"); -+ -+ return 0; -+ -+ probe_free_irq: -+ free_irq(host->irq, host); -+ -+ probe_free_mem_region: -+ release_mem_region(host->mem->start, resource_size(host->mem)); -+ -+probe_free_wq: -+ destroy_workqueue(mywq); -+ -+ probe_free_host: -+ mmc_free_host(mmc); -+ -+ probe_out: -+ return ret; -+} -+ -+static void ftsdc_shutdown(struct platform_device *pdev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ struct ftsdc_host *host = mmc_priv(mmc); -+ -+ flush_workqueue(mywq); -+ destroy_workqueue(mywq); -+ -+ ftsdc_debugfs_remove(host); -+ mmc_remove_host(mmc); -+} -+ -+static int __devexit ftsdc_remove(struct platform_device *pdev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ struct ftsdc_host *host = mmc_priv(mmc); -+ -+ ftsdc_shutdown(pdev); -+ -+ tasklet_disable(&host->pio_tasklet); -+ -+ if (ftsdc_dmaexist(host)) -+ kfree(host->dma_req); -+ -+ free_irq(host->irq, host); -+ -+ release_mem_region(host->mem->start, resource_size(host->mem)); -+ -+ mmc_free_host(mmc); -+ return 0; -+} -+ -+ -+#ifdef CONFIG_PM -+static int ftsdc_free_dma(struct ftsdc_host *host) -+{ -+ dmad_channel_free(host->dma_req); -+ return 0; -+} -+ -+static int ftsdc_suspend(struct platform_device *pdev, pm_message_t state) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ struct ftsdc_host *host = mmc_priv(mmc); -+ int ret = 0; -+ if (mmc) { -+ ftsdc_free_dma(host); -+ ret = mmc_suspend_host(mmc); -+ } -+ return ret; -+ -+} -+ -+static int ftsdc_resume(struct platform_device *pdev) -+{ -+ struct mmc_host *mmc = platform_get_drvdata(pdev); -+ int ret = 0; -+ struct ftsdc_host *host = mmc_priv(mmc); -+ if (mmc) { -+#if (defined(CONFIG_PLATFORM_AHBDMA) || defined(CONFIG_PLATFORM_APBDMA)) -+ ftsdc_alloc_dma(host); -+#endif -+ ret = mmc_resume_host(mmc); -+ } -+ return ret; -+} -+ -+static void platform_device_release(struct device *dev){ -+} -+ -+ -+#else -+#define ftsdc_suspend NULL -+#define ftsdc_resume NULL -+#endif -+ -+ -+static struct platform_driver ftsdc_driver = { -+ .driver = { -+ .name = "ftsdc010", -+ .owner = THIS_MODULE, -+ }, -+ .probe = ftsdc_probe, -+ .remove = __devexit_p(ftsdc_remove), -+ .shutdown = ftsdc_shutdown, -+ .suspend = ftsdc_suspend, -+ .resume = ftsdc_resume, -+}; -+ -+static struct resource sdc_resource[] = { -+ [0] = { -+ .start = SDC_FTSDC010_0_VA_BASE, -+ .end = SDC_FTSDC010_0_VA_BASE + 0x1000 - 1, -+ .flags = IORESOURCE_MEM, -+ }, -+ [1] = { -+ .start = SDC_FTSDC010_0_IRQ, -+ .flags = IORESOURCE_IRQ, -+ } -+ -+}; -+ -+struct platform_device sdc_device = { -+ .name = "ftsdc010", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(sdc_resource), -+ .resource = sdc_resource, -+ .dev = { -+ .release = platform_device_release, -+ }, -+}; -+ -+static int __init ftsdc_init(void) -+{ -+ platform_device_register(&sdc_device); -+ return platform_driver_register(&ftsdc_driver); -+} -+ -+static void __exit ftsdc_exit(void) -+{ -+ platform_driver_unregister(&ftsdc_driver); -+ platform_device_unregister(&sdc_device); -+} -+module_init(ftsdc_init); -+module_exit(ftsdc_exit); -+ -+MODULE_DESCRIPTION("Andestech Leopard MMC/SD Card Interface driver"); -+MODULE_LICENSE("GPL v2"); -diff -Nur linux-3.4.113.orig/drivers/mmc/host/ftsdc010.h linux-3.4.113/drivers/mmc/host/ftsdc010.h ---- linux-3.4.113.orig/drivers/mmc/host/ftsdc010.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/mmc/host/ftsdc010.h 2016-12-01 20:59:24.388614139 +0100 -@@ -0,0 +1,240 @@ -+/* -+ * linux/driver/mmc/ftsdc010.h - Andestech MMC/SD driver -+ * Andestech FTSDC010 Device Driver -+ * -+ * Andestech (C) 2005 Faraday Corp. (http://www.Andestech.com) -+ * -+ * All Rights Reserved -+ */ -+ -+#ifndef _FTSDC010_H_ -+#define _FTSDC010_H_ -+ -+//#define SD_DEBUG -+#define DELAY_FOR_DMA_READ -+ -+#ifdef SD_DEBUG -+ #define P_DEBUG(fmt, args...) printk(KERN_ALERT "SD: " fmt, ## args) -+#else -+ #define P_DEBUG(a...) -+#endif -+#define P_DEBUGG(a...) -+ -+/* used for dma timeout */ -+#define SDC_TIMEOUT_BASE (HZ/2) // Unit is 500 ms -+ -+/* used for pio retry times */ -+#define SDC_PIO_RETRY 0x300000 -+ -+/* sd controller register */ -+#define SDC_CMD_REG 0x00000000 -+#define SDC_ARGU_REG 0x00000004 -+#define SDC_RESPONSE0_REG 0x00000008 -+#define SDC_RESPONSE1_REG 0x0000000C -+#define SDC_RESPONSE2_REG 0x00000010 -+#define SDC_RESPONSE3_REG 0x00000014 -+#define SDC_RSP_CMD_REG 0x00000018 -+#define SDC_DATA_CTRL_REG 0x0000001C -+#define SDC_DATA_TIMER_REG 0x00000020 -+#define SDC_DATA_LEN_REG 0x00000024 -+#define SDC_STATUS_REG 0x00000028 -+#define SDC_CLEAR_REG 0x0000002C -+#define SDC_INT_MASK_REG 0x00000030 -+#define SDC_POWER_CTRL_REG 0x00000034 -+#define SDC_CLOCK_CTRL_REG 0x00000038 -+#define SDC_BUS_WIDTH_REG 0x0000003C -+#define SDC_DATA_WINDOW_REG 0x00000040 -+ -+#ifdef A320D_BUILDIN_SDC -+#define SDC_FEATURE_REG 0x00000044 -+#define SDC_REVISION_REG 0x00000048 -+#else -+#define SDC_MMC_INT_RSP_REG 0x00000044 -+#define SDC_GP_OUTPUT_REG 0x00000048 -+#define SDC_FEATURE_REG 0x0000009C -+#define SDC_REVISION_REG 0x000000A0 -+#endif -+ -+#define SDC_SDIO_CTRL1_REG 0x0000006C -+#define SDC_SDIO_CTRL2_REG 0x00000070 -+#define SDC_SDIO_STATUS_REG 0x00000074 -+ -+/* bit mapping of command register */ -+#define SDC_CMD_REG_INDEX 0x0000003F -+#define SDC_CMD_REG_NEED_RSP 0x00000040 -+#define SDC_CMD_REG_LONG_RSP 0x00000080 -+#define SDC_CMD_REG_APP_CMD 0x00000100 -+#define SDC_CMD_REG_CMD_EN 0x00000200 -+#define SDC_CMD_REG_SDC_RST 0x00000400 -+#define SDC_CMD_MMC_INT_STOP 0x00000800 -+ -+/* bit mapping of response command register */ -+#define SDC_RSP_CMD_REG_INDEX 0x0000003F -+#define SDC_RSP_CMD_REG_APP 0x00000040 -+ -+/* bit mapping of data control register */ -+#define SDC_DATA_CTRL_REG_BLK_SIZE 0x0000000F -+#define SDC_DATA_CTRL_REG_DATA_WRITE 0x00000010 -+#define SDC_DATA_CTRL_REG_DMA_EN 0x00000020 -+#define SDC_DATA_CTRL_REG_DATA_EN 0x00000040 -+#define SDC_DATA_CTRL_REG_FIFOTH 0x00000080 -+#define SDC_DATA_CTRL_REG_DMA_TYPE 0x00000300 -+#define SDC_DATA_CTRL_REG_FIFO_RST 0x00000400 -+#define SDC_CPRM_DATA_CHANGE_ENDIAN_EN 0x00000800 -+#define SDC_CPRM_DATA_SWAP_HL_EN 0x00001000 -+ -+#define SDC_DMA_TYPE_1 0x00000000 -+#define SDC_DMA_TYPE_4 0x00000100 -+#define SDC_DMA_TYPE_8 0x00000200 -+ -+/* bit mapping of status register */ -+#define SDC_STATUS_REG_RSP_CRC_FAIL 0x00000001 -+#define SDC_STATUS_REG_DATA_CRC_FAIL 0x00000002 -+#define SDC_STATUS_REG_RSP_TIMEOUT 0x00000004 -+#define SDC_STATUS_REG_DATA_TIMEOUT 0x00000008 -+#define SDC_STATUS_REG_RSP_CRC_OK 0x00000010 -+#define SDC_STATUS_REG_DATA_CRC_OK 0x00000020 -+#define SDC_STATUS_REG_CMD_SEND 0x00000040 -+#define SDC_STATUS_REG_DATA_END 0x00000080 -+#define SDC_STATUS_REG_FIFO_UNDERRUN 0x00000100 -+#define SDC_STATUS_REG_FIFO_OVERRUN 0x00000200 -+#define SDC_STATUS_REG_CARD_CHANGE 0x00000400 -+#define SDC_STATUS_REG_CARD_DETECT 0x00000800 -+#define SDC_STATUS_REG_CARD_LOCK 0x00001000 -+#define SDC_STATUS_REG_CP_READY 0x00002000 -+#define SDC_STATUS_REG_CP_BUF_READY 0x00004000 -+#define SDC_STATUS_REG_PLAIN_TEXT_READY 0x00008000 -+#define SDC_STATUS_REG_SDIO_INTR 0x00010000 -+ -+/* bit mapping of clear register */ -+#define SDC_CLEAR_REG_RSP_CRC_FAIL 0x00000001 -+#define SDC_CLEAR_REG_DATA_CRC_FAIL 0x00000002 -+#define SDC_CLEAR_REG_RSP_TIMEOUT 0x00000004 -+#define SDC_CLEAR_REG_DATA_TIMEOUT 0x00000008 -+#define SDC_CLEAR_REG_RSP_CRC_OK 0x00000010 -+#define SDC_CLEAR_REG_DATA_CRC_OK 0x00000020 -+#define SDC_CLEAR_REG_CMD_SEND 0x00000040 -+#define SDC_CLEAR_REG_DATA_END 0x00000080 -+#define SDC_CLEAR_REG_CARD_CHANGE 0x00000400 -+#define SDC_CLEAR_REG_SDIO_INTR 0x00010000 -+ -+/* bit mapping of int_mask register */ -+#define SDC_INT_MASK_REG_RSP_CRC_FAIL 0x00000001 -+#define SDC_INT_MASK_REG_DATA_CRC_FAIL 0x00000002 -+#define SDC_INT_MASK_REG_RSP_TIMEOUT 0x00000004 -+#define SDC_INT_MASK_REG_DATA_TIMEOUT 0x00000008 -+#define SDC_INT_MASK_REG_RSP_CRC_OK 0x00000010 -+#define SDC_INT_MASK_REG_DATA_CRC_OK 0x00000020 -+#define SDC_INT_MASK_REG_CMD_SEND 0x00000040 -+#define SDC_INT_MASK_REG_DATA_END 0x00000080 -+#define SDC_INT_MASK_REG_FIFO_UNDERRUN 0x00000100 -+#define SDC_INT_MASK_REG_FIFO_OVERRUN 0x00000200 -+#define SDC_INT_MASK_REG_CARD_CHANGE 0x00000400 -+#define SDC_INT_MASK_REG_CARD_LOCK 0x00001000 -+#define SDC_INT_MASK_REG_CP_READY 0x00002000 -+#define SDC_INT_MASK_REG_CP_BUF_READY 0x00004000 -+#define SDC_INT_MASK_REG_PLAIN_TEXT_READY 0x00008000 -+#define SDC_INT_MASK_REG_SDIO_INTR 0x00010000 -+ -+ -+#define SDC_CARD_INSERT 0x0 -+#define SDC_CARD_REMOVE SDC_STATUS_REG_CARD_DETECT -+ -+/* bit mapping of power control register */ -+#define SDC_POWER_CTRL_REG_POWER_ON 0x00000010 -+#define SDC_POWER_CTRL_REG_POWER_BITS 0x0000000F -+ -+/* bit mapping of clock control register */ -+#define SDC_CLOCK_CTRL_REG_CLK_DIV 0x0000007F -+#define SDC_CLOCK_CTRL_REG_CARD_TYPE 0x00000080 -+#define SDC_CLOCK_CTRL_REG_CLK_DIS 0x00000100 -+ -+/* card type */ -+#define SDC_CARD_TYPE_SD SDC_CLOCK_REG_CARD_TYPE -+#define SDC_CARD_TYPE_MMC 0x0 -+ -+/* bit mapping of bus width register */ -+#define SDC_BUS_WIDTH_REG_SINGLE_BUS 0x00000001 -+#define SDC_BUS_WIDTH_REG_WIDE_8_BUS 0x00000002 -+#define SDC_BUS_WIDTH_REG_WIDE_4_BUS 0x00000004 -+#define SDC_BUS_WIDTH_REG_WIDE_BUS_SUPPORT 0x00000018 -+#define SDC_BUS_WIDTH_REG_CARD_DETECT 0x00000020 -+ -+#define SDC_WIDE_4_BUS_SUPPORT 0x00000008 -+#define SDC_WIDE_8_BUS_SUPPORT 0x00000010 -+ -+/* bit mapping of feature register */ -+#define SDC_FEATURE_REG_FIFO_DEPTH 0x000000FF -+#define SDC_FEATURE_REG_CPRM_FUNCTION 0x00000100 -+ -+/* bit mapping of sdio control register */ -+#define SDC_SDIO_CTRL1_REG_SDIO_BLK_NO 0xFFFF8000 -+#define SDC_SDIO_CTRL1_REG_SDIO_ENABLE 0x00004000 -+#define SDC_SDIO_CTRL1_REG_READ_WAIT_ENABLE 0x00002000 -+#define SDC_SDIO_CTRL1_REG_SDIO_BLK_MODE 0x00001000 -+#define SDC_SDIO_CTRL1_REG_SDIO_BLK_SIZE 0x00000FFF -+ -+/* bit mapping of sdio status register */ -+#define SDC_SDIO_SDIO_STATUS_REG_FIFO_REMAIN_NO 0x00FE0000 -+#define SDC_SDIO_SDIO_STATUS_REG_SDIO_BLK_CNT 0x0001FFFF -+ -+enum ftsdc_waitfor { -+ COMPLETION_NONE, -+ COMPLETION_FINALIZE, -+ COMPLETION_CMDSENT, -+ COMPLETION_RSPFIN, -+ COMPLETION_XFER_PROGRESS, -+}; -+ -+struct ftsdc_host { -+ struct platform_device *pdev; -+ struct mmc_host *mmc; -+ struct resource *mem; -+ struct clk *clk; -+ void __iomem *base; -+ int irq; -+ -+ unsigned int real_rate; -+ bool irq_enabled; -+ unsigned int fifo_len; /* bytes */ -+ unsigned int last_opcode; /* keep last successful cmd to judge application specific command */ -+ -+ struct mmc_request *mrq; -+ int cmd_is_stop; -+ -+ spinlock_t complete_lock; -+ enum ftsdc_waitfor complete_what; -+ -+ struct completion dma_complete; -+ dmad_chreq *dma_req; -+ bool dodma; -+ bool dma_finish; -+ -+ -+ u32 buf_sgptr; /* keep next scallterlist buffer index */ -+ u32 buf_bytes; /* keep current total scallterlist buffer length */ -+ u32 buf_count; /* keep real data size rw from sd */ -+ u32 *buf_ptr; /* keep current scallterlist buffer address */ -+#define XFER_NONE 0 -+#define XFER_READ 1 -+#define XFER_WRITE 2 -+ u32 buf_active; /* keep current transfer mode */ -+ -+ int bus_width; -+ -+ char dbgmsg_cmd[301]; -+ char dbgmsg_dat[301]; -+ char *status; -+ -+ unsigned int ccnt, dcnt; -+ struct tasklet_struct pio_tasklet; -+ struct work_struct work; -+ -+#ifdef CONFIG_DEBUG_FS -+ struct dentry *debug_root; -+ struct dentry *debug_state; -+ struct dentry *debug_regs; -+#endif -+}; -+ -+#endif -diff -Nur linux-3.4.113.orig/drivers/mmc/host/Kconfig linux-3.4.113/drivers/mmc/host/Kconfig ---- linux-3.4.113.orig/drivers/mmc/host/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/mmc/host/Kconfig 2016-12-01 20:59:24.388614139 +0100 -@@ -609,3 +609,8 @@ - - Note: These controllers only support SDIO cards and do not - support MMC or SD memory cards. -+ -+config MMC_FTSDC010 -+ tristate "Andestech MMC/SD function support" -+ depends on NDS32 && !FTSDC010 -+ -diff -Nur linux-3.4.113.orig/drivers/mmc/host/Makefile linux-3.4.113/drivers/mmc/host/Makefile ---- linux-3.4.113.orig/drivers/mmc/host/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/mmc/host/Makefile 2016-12-01 20:59:24.388614139 +0100 -@@ -45,6 +45,7 @@ - obj-$(CONFIG_MMC_JZ4740) += jz4740_mmc.o - obj-$(CONFIG_MMC_VUB300) += vub300.o - obj-$(CONFIG_MMC_USHC) += ushc.o -+obj-$(CONFIG_MMC_FTSDC010) += ftsdc010.o - - obj-$(CONFIG_MMC_SDHCI_PLTFM) += sdhci-pltfm.o - obj-$(CONFIG_MMC_SDHCI_CNS3XXX) += sdhci-cns3xxx.o -diff -Nur linux-3.4.113.orig/drivers/net/ethernet/faraday/ftmac100.c linux-3.4.113/drivers/net/ethernet/faraday/ftmac100.c ---- linux-3.4.113.orig/drivers/net/ethernet/faraday/ftmac100.c 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/net/ethernet/faraday/ftmac100.c 2016-12-01 20:59:24.388614139 +0100 -@@ -1,1202 +1,1210 @@ - /* -- * Faraday FTMAC100 10/100 Ethernet -+ * drivers/net/ftmac100.c - * -- * (C) Copyright 2009-2011 Faraday Technology -- * Po-Yu Chuang -+ * Faraday FTMAC100 Device Driver - * -- * 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. -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * All Rights Reserved - * -- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. - */ - --#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt -- --#include --#include --#include -+#include - #include -+#include -+ -+#include -+#include /* printk() */ -+#include /* kmalloc() */ -+#include /* error codes */ -+#include /* size_t */ - #include --#include --#include --#include --#include -+ -+#include - #include -+#include /* struct device, and other headers */ -+#include /* eth_type_trans */ -+#include /* struct iphdr */ -+#include /* struct tcphdr */ -+#include -+ -+#include -+#include -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include - -+#include // dma_clean_range -+#include - #include "ftmac100.h" - --#define DRV_NAME "ftmac100" --#define DRV_VERSION "0.2" -- --#define RX_QUEUE_ENTRIES 128 /* must be power of 2 */ --#define TX_QUEUE_ENTRIES 16 /* must be power of 2 */ -+#define IPMODULE MAC -+#define IPNAME FTMAC100 - --#define MAX_PKT_SIZE 1518 --#define RX_BUF_SIZE 2044 /* must be smaller than 0x7ff */ -+#define ENABLE_BOTTOM_HALF 0 -+#define ZERO_COPY 1 - --#if MAX_PKT_SIZE > 0x7ff --#error invalid MAX_PKT_SIZE --#endif -- --#if RX_BUF_SIZE > 0x7ff || RX_BUF_SIZE > PAGE_SIZE --#error invalid RX_BUF_SIZE --#endif -- --/****************************************************************************** -- * private data -- *****************************************************************************/ --struct ftmac100_descs { -- struct ftmac100_rxdes rxdes[RX_QUEUE_ENTRIES]; -- struct ftmac100_txdes txdes[TX_QUEUE_ENTRIES]; --}; -- --struct ftmac100 { -- struct resource *res; -- void __iomem *base; -- int irq; -- -- struct ftmac100_descs *descs; -- dma_addr_t descs_dma_addr; -- -- unsigned int rx_pointer; -- unsigned int tx_clean_pointer; -- unsigned int tx_pointer; -- unsigned int tx_pending; -- -- spinlock_t tx_lock; -- -- struct net_device *netdev; -- struct device *dev; -- struct napi_struct napi; -+#define FTMAC100_DEBUG 0 -+#define CARDNAME "FTMAC100" - -- struct mii_if_info mii; --}; -- --static int ftmac100_alloc_rx_page(struct ftmac100 *priv, -- struct ftmac100_rxdes *rxdes, gfp_t gfp); -- --/****************************************************************************** -- * internal functions (hardware register access) -- *****************************************************************************/ --#define INT_MASK_ALL_ENABLED (FTMAC100_INT_RPKT_FINISH | \ -- FTMAC100_INT_NORXBUF | \ -- FTMAC100_INT_XPKT_OK | \ -- FTMAC100_INT_XPKT_LOST | \ -- FTMAC100_INT_RPKT_LOST | \ -- FTMAC100_INT_AHB_ERR | \ -- FTMAC100_INT_PHYSTS_CHG) -+MODULE_AUTHOR("Faraday Corp."); -+MODULE_LICENSE("GPL"); - --#define INT_MASK_ALL_DISABLED 0 -+static const char version[] = "Faraday FTMAC100 Driver (Linux 2.6) 09/28/05 - (C) 2005 Faraday Corp.\n"; -+static volatile int trans_busy = 0; -+static const char mac_string[] = "Faraday MAC"; - --static void ftmac100_enable_all_int(struct ftmac100 *priv) --{ -- iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTMAC100_OFFSET_IMR); --} -+#if FTMAC100_DEBUG > 2 -+static void print_packet( unsigned char * buf, int length ); -+#endif - --static void ftmac100_disable_all_int(struct ftmac100 *priv) --{ -- iowrite32(INT_MASK_ALL_DISABLED, priv->base + FTMAC100_OFFSET_IMR); --} -+#if FTMAC100_DEBUG > 0 -+#define PRINTK printk -+#else -+#define PRINTK(x...) -+#endif - --static void ftmac100_set_rx_ring_base(struct ftmac100 *priv, dma_addr_t addr) --{ -- iowrite32(addr, priv->base + FTMAC100_OFFSET_RXR_BADR); -+static int ftmac100_open(struct net_device *dev); -+static void ftmac100_timeout (struct net_device *dev); -+static int ftmac100_close(struct net_device *dev); -+static struct net_device_stats * ftmac100_query_statistics( struct net_device *dev); -+#ifdef HAVE_MULTICAST -+static void ftmac100_set_multicast_list(struct net_device *dev); -+#endif -+static void ftmac100_phy_configure(struct net_device* dev) {}; -+static irqreturn_t ftmac100_interrupt(int irq, void * dev_id); -+static void ftmac100_rcv(void *dev); -+static int ftmac100_setup(struct net_device *dev); -+static int ftmac100_reset( struct net_device* dev ); -+static void ftmac100_enable( struct net_device *dev ); -+ -+static void put_mac(int base, unsigned char *mac_addr) -+{ -+ int val; -+ -+ val = ((u32)mac_addr[0])<<8 | (u32)mac_addr[1]; -+ outl(val, base); -+ val = ((((u32)mac_addr[2])<<24)&0xff000000) | -+ ((((u32)mac_addr[3])<<16)&0xff0000) | -+ ((((u32)mac_addr[4])<<8)&0xff00) | -+ ((((u32)mac_addr[5])<<0)&0xff); -+ outl(val, base+4); -+} -+ -+static void get_mac(int base, unsigned char *mac_addr) -+{ -+ int val; -+ -+ //printk("+get_mac\n"); -+ -+ val = inl(base); -+ mac_addr[0] = (val>>8)&0xff; -+ mac_addr[1] = val&0xff; -+ val = inl(base+4); //john add +4 -+ mac_addr[2] = (val>>24)&0xff; -+ mac_addr[3] = (val>>16)&0xff; -+ mac_addr[4] = (val>>8)&0xff; -+ mac_addr[5] = val&0xff; -+} -+ -+static void auto_get_mac(int id,unsigned char *mac_addr) -+{ -+ get_mac(MAC_FTMAC100_0_VA_BASE + MAC_MADR_REG, mac_addr); -+ -+ if (memcmp(mac_addr, "\0\0\0\0\0\0", 6) == 0) { -+ mac_addr[0]=0; -+ mac_addr[1]=0x23; -+ mac_addr[2]=0x96; -+ mac_addr[3]=0x00; -+ mac_addr[4]=0xff; -+ mac_addr[5]=0x00; -+ } - } - --static void ftmac100_set_tx_ring_base(struct ftmac100 *priv, dma_addr_t addr) -+/* -+ * Print the Ethernet address -+ */ -+static void ft_print_mac(unsigned char *mac_addr) - { -- iowrite32(addr, priv->base + FTMAC100_OFFSET_TXR_BADR); -+ printk("ADDR: %pM\n", mac_addr); - } - --static void ftmac100_txdma_start_polling(struct ftmac100 *priv) --{ -- iowrite32(1, priv->base + FTMAC100_OFFSET_TXPD); --} - --static int ftmac100_reset(struct ftmac100 *priv) -+#ifdef HAVE_MULTICAST -+/* -+ * Finds the CRC32 of a set of bytes. -+ * Again, from Peter Cammaert's code. -+ */ -+static int crc32( char * s, int length ) - { -- struct net_device *netdev = priv->netdev; -- int i; -- -- /* NOTE: reset clears all registers */ -- iowrite32(FTMAC100_MACCR_SW_RST, priv->base + FTMAC100_OFFSET_MACCR); -- -- for (i = 0; i < 5; i++) { -- unsigned int maccr; -- -- maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR); -- if (!(maccr & FTMAC100_MACCR_SW_RST)) { -- /* -- * FTMAC100_MACCR_SW_RST cleared does not indicate -- * that hardware reset completed (what the f*ck). -- * We still need to wait for a while. -- */ -- udelay(500); -- return 0; -+ /* indices */ -+ int perByte; -+ int perBit; -+ /* crc polynomial for Ethernet */ -+ const unsigned long poly = 0xedb88320; -+ /* crc value - preinitialized to all 1's */ -+ unsigned long crc_value = 0xffffffff; -+ -+ //printk("+crc32\n"); -+ -+ for ( perByte = 0; perByte < length; perByte ++ ) { -+ unsigned char c; -+ -+ c = *(s++); -+ for ( perBit = 0; perBit < 8; perBit++ ) { -+ crc_value = (crc_value>>1)^ -+ (((crc_value^c)&0x01)?poly:0); -+ c >>= 1; - } -- -- udelay(1000); - } -- -- netdev_err(netdev, "software reset failed\n"); -- return -EIO; --} -- --static void ftmac100_set_mac(struct ftmac100 *priv, const unsigned char *mac) --{ -- unsigned int maddr = mac[0] << 8 | mac[1]; -- unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; -- -- iowrite32(maddr, priv->base + FTMAC100_OFFSET_MAC_MADR); -- iowrite32(laddr, priv->base + FTMAC100_OFFSET_MAC_LADR); -+ return crc_value; - } -+#endif - --#define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \ -- FTMAC100_MACCR_RCV_EN | \ -- FTMAC100_MACCR_XDMA_EN | \ -- FTMAC100_MACCR_RDMA_EN | \ -- FTMAC100_MACCR_CRC_APD | \ -- FTMAC100_MACCR_FULLDUP | \ -- FTMAC100_MACCR_RX_RUNT | \ -- FTMAC100_MACCR_RX_BROADPKT) -- --static int ftmac100_start_hw(struct ftmac100 *priv) -+static int ftmac100_reset( struct net_device* dev ) - { -- struct net_device *netdev = priv->netdev; -+ unsigned ioaddr = dev->base_addr; -+ int rcount; - -- if (ftmac100_reset(priv)) -- return -EIO; -+ PRINTK("+ftmac100_reset:I/O addr=%X\n", ioaddr); - -- /* setup ring buffer base registers */ -- ftmac100_set_rx_ring_base(priv, -- priv->descs_dma_addr + -- offsetof(struct ftmac100_descs, rxdes)); -- ftmac100_set_tx_ring_base(priv, -- priv->descs_dma_addr + -- offsetof(struct ftmac100_descs, txdes)); -+ outl( SW_RST_bit, ioaddr + MACCR_REG ); - -- iowrite32(FTMAC100_APTC_RXPOLL_CNT(1), priv->base + FTMAC100_OFFSET_APTC); -+ /* this should pause enough for the chip to be happy */ -+ for (rcount = 0; (inl( ioaddr + MACCR_REG ) & SW_RST_bit) != 0; rcount++) { -+ //mdelay(10); -+ msleep_interruptible(10); -+ if (rcount > 5) // Retry 5 times -+ return -ENODEV; -+ } - -- ftmac100_set_mac(priv, netdev->dev_addr); -+ outl( 0, ioaddr + IMR_REG ); /* Disable all interrupts */ -+ if (inl(ioaddr+IMR_REG)!=0) -+ return -ENODEV; - -- iowrite32(MACCR_ENABLE_ALL, priv->base + FTMAC100_OFFSET_MACCR); -- return 0; -+ return 0; - } - --static void ftmac100_stop_hw(struct ftmac100 *priv) --{ -- iowrite32(0, priv->base + FTMAC100_OFFSET_MACCR); --} - --/****************************************************************************** -- * internal functions (receive descriptor) -- *****************************************************************************/ --static bool ftmac100_rxdes_first_segment(struct ftmac100_rxdes *rxdes) --{ -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FRS); --} -- --static bool ftmac100_rxdes_last_segment(struct ftmac100_rxdes *rxdes) -+/* -+ . Function: ftmac100_enable -+ . Purpose: let the chip talk to the outside work -+ . Method: -+ . 1. Enable the transmitter -+ . 2. Enable the receiver -+ . 3. Enable interrupts -+*/ -+static void ftmac100_enable( struct net_device *dev ) - { -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_LRS); --} -+ unsigned int ioaddr = dev->base_addr; -+ int i; -+ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); -+ char mac_addr[6]; - --static bool ftmac100_rxdes_owned_by_dma(struct ftmac100_rxdes *rxdes) --{ -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN); --} -+ //printk("+ftmac100_enable\n"); -+ PRINTK("%s:ftmac100_enable ioaddr=%X\n", dev->name, ioaddr); - --static void ftmac100_rxdes_set_dma_own(struct ftmac100_rxdes *rxdes) --{ -- /* clear status bits */ -- rxdes->rxdes0 = cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN); -+ for (i=0; irx_descs[i].RXDMA_OWN = OWNBY_FTMAC100; // owned by FTMAC100 -+ } -+ priv->rx_idx = 0; -+ -+ for (i=0; itx_descs[i].TXDMA_OWN = OWNBY_SOFTWARE; // owned by software -+ } -+ priv->tx_idx = 0; -+ -+ -+ /* set the MAC address */ -+ put_mac(ioaddr + MAC_MADR_REG, dev->dev_addr); -+ -+ //john add -+ get_mac(ioaddr + MAC_MADR_REG, mac_addr); -+ ft_print_mac(mac_addr); -+ -+ outl( priv->rx_descs_dma, ioaddr + RXR_BADR_REG); -+ outl( priv->tx_descs_dma, ioaddr + TXR_BADR_REG); -+ outl( 0x00001010, ioaddr + ITC_REG); // TODO: threshold too small -+ outl( (0UL<maccr_val, ioaddr + MACCR_REG ); -+ PRINTK("%s:ftmac100_enable DONE\n", dev->name); - } - --static bool ftmac100_rxdes_rx_error(struct ftmac100_rxdes *rxdes) -+/* -+ . Function: ftmac100_shutdown -+ . Purpose: closes down the SMC91xxx chip. -+ . Method: -+ . 1. zero the interrupt mask -+ . 2. clear the enable receive flag -+ . 3. clear the enable xmit flags -+ . -+ . TODO: -+ . (1) maybe utilize power down mode. -+ . Why not yet? Because while the chip will go into power down mode, -+ . the manual says that it will wake up in response to any I/O requests -+ . in the register space. Empirical results do not show this working. -+*/ -+static void ftmac100_shutdown( unsigned int ioaddr ) - { -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ERR); --} -+ //printk("+ftmac100_shutdown\n"); - --static bool ftmac100_rxdes_crc_error(struct ftmac100_rxdes *rxdes) --{ -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_CRC_ERR); -+ outl( 0, ioaddr + IMR_REG ); -+ outl( 0, ioaddr + MACCR_REG ); - } - --static bool ftmac100_rxdes_frame_too_long(struct ftmac100_rxdes *rxdes) -+/* -+ * Function: ftmac100_wait_to_send_packet( struct sk_buff * skb, struct device * ) -+ * Purpose: -+ * Attempt to allocate memory for a packet, if chip-memory is not -+ * available, then tell the card to generate an interrupt when it -+ * is available* -+ * -+ * Algorithm: -+ * -+ * o if the saved_skb is not currently null, then drop this packet -+ * on the floor. This should never happen, because of TBUSY. -+ * o if the saved_skb is null, then replace it with the current packet, -+ * o See if I can sending it now. -+ * o (NO): Enable interrupts and let the interrupt handler deal with it. -+ * o (YES):Send it now. -+ */ -+static int ftmac100_wait_to_send_packet( struct sk_buff * skb, struct net_device * dev ) - { -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FTL); --} -+ struct ftmac100_local *priv=(struct ftmac100_local *)netdev_priv(dev); -+ unsigned int ioaddr=dev->base_addr; -+ volatile TX_DESC *cur_desc; -+ int length; -+ unsigned long flags; -+ -+ //printk("+ftmac100_wait_to_send_packet\n"); -+ -+ spin_lock_irqsave(&priv->lock, flags); -+ if (skb==NULL) { -+ printk("%s(%d): NULL skb???\n", __FILE__,__LINE__); -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return 0; -+ } -+ -+ cur_desc = &priv->tx_descs[priv->tx_idx]; -+#if ZERO_COPY -+ /* Record buffer address to be freed later */ -+ priv->tx_skbuff[priv->tx_idx] = skb; -+#endif -+ -+#ifdef not_complete_yet -+ if (cur_desc->TXDMA_OWN != TX_OWNBY_SOFTWARE) /// no empty transmit descriptor -+ { -+ DO_PRINT("no empty transmit descriptor\n"); -+ DO_PRINT("jiffies = %d\n", jiffies); -+ lp->stats.tx_dropped++; -+ netif_stop_queue(dev); /// waiting to do: -+ spin_unlock_irqrestore(&lp->lock, flags); -+ -+ return 1; -+ } -+#endif /* end_of_not */ -+ -+ for (; cur_desc->TXDMA_OWN != OWNBY_SOFTWARE; ) { -+ PRINTK( KERN_WARNING "NO empty TX\n"); //printk("no empty TX descriptor:0x%x:0x%x\n",(unsigned)cur_desc,(unsigned)cur_desc[0]); -+ udelay(1); -+ } -+ length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; -+ length = min(length, TX_BUF_SIZE); // truncate jumbo packets -+ -+#if FTMAC100_DEBUG > 2 -+ printk("Transmitting Packet at 0x%x\n",(unsigned int)cur_desc->VIR_TXBUF_BADR); -+ print_packet( skb->data, length ); -+#endif - --static bool ftmac100_rxdes_runt(struct ftmac100_rxdes *rxdes) --{ -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RUNT); --} -+#if ZERO_COPY -+ cur_desc->VIR_TXBUF_BADR = (unsigned)skb->data; -+ cur_desc->TXBUF_BADR = virt_to_phys(skb->data); -+ cpu_dma_wb_range((unsigned)skb->data, ((unsigned)(skb->data) + length + CACHE_LINE_SIZE( DCACHE) - 1 )&(~(CACHE_LINE_SIZE( DCACHE)-1)) ); - --static bool ftmac100_rxdes_odd_nibble(struct ftmac100_rxdes *rxdes) --{ -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ODD_NB); --} -+#else -+ memcpy((char *)cur_desc->VIR_TXBUF_BADR, skb->data, length); -+#endif - --static unsigned int ftmac100_rxdes_frame_length(struct ftmac100_rxdes *rxdes) --{ -- return le32_to_cpu(rxdes->rxdes0) & FTMAC100_RXDES0_RFL; -+ cur_desc->TXBUF_Size = length; -+ cur_desc->LTS = 1; -+ cur_desc->FTS = 1; -+ -+ cur_desc->TX2FIC = 0; -+ cur_desc->TXIC = 0; -+ -+ cur_desc->TXDMA_OWN = OWNBY_FTMAC100; -+ -+ outl( 0xffffffff, ioaddr + TXPD_REG ); -+ -+ priv->tx_idx = (priv->tx_idx + 1) & (TXDES_NUM-1); -+ priv->stats.tx_packets++; -+ priv->stats.tx_bytes += skb->len; -+#if !ZERO_COPY -+ dev_kfree_skb_any (skb); -+#endif -+ dev->trans_start = jiffies; -+ spin_unlock_irqrestore(&priv->lock, flags); -+ return 0; - } - --static bool ftmac100_rxdes_multicast(struct ftmac100_rxdes *rxdes) --{ -- return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_MULTICAST); --} -+//#define dma_allocate(x,y,z,w) dma_alloc_coherent((x),(y),(dma_addr_t*)(z),(w)) -+#define dma_allocate(x,y,z,w) dma_alloc_writecombine((x),(y),(dma_addr_t*)(z),(w)) - --static void ftmac100_rxdes_set_buffer_size(struct ftmac100_rxdes *rxdes, -- unsigned int size) -+static int ftmac100_ringbuf_alloc(struct net_device *dev,struct ftmac100_local *priv) - { -- rxdes->rxdes1 &= cpu_to_le32(FTMAC100_RXDES1_EDORR); -- rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_RXBUF_SIZE(size)); --} -+ int i; - --static void ftmac100_rxdes_set_end_of_ring(struct ftmac100_rxdes *rxdes) --{ -- rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_EDORR); --} -+ //printk("+ftmac100_ringbuf_alloc\n"); - --static void ftmac100_rxdes_set_dma_addr(struct ftmac100_rxdes *rxdes, -- dma_addr_t addr) --{ -- rxdes->rxdes2 = cpu_to_le32(addr); --} -+ priv->rx_descs = dma_allocate( NULL, sizeof(RX_DESC)*RXDES_NUM, &(priv->rx_descs_dma), GFP_KERNEL ); -+ if (priv->rx_descs == NULL || (( (u32)priv->rx_descs & 0xf)!=0)) { -+ printk("Receive Ring Buffer allocation error\n"); -+ return -ENOMEM; -+ } -+#if FTMAC100_DEBUG > 2 -+ else -+ printk( KERN_INFO "* Allocated RX descs=%X, bus addr=%X, size=%d*%d=%d\n", -+ (unsigned)priv->rx_descs, (unsigned)priv->rx_descs_dma, -+ sizeof(RX_DESC),RXDES_NUM,sizeof(RX_DESC)*RXDES_NUM ); -+#endif -+ memset((unsigned int *)priv->rx_descs, 0, sizeof(RX_DESC)*RXDES_NUM); - --static dma_addr_t ftmac100_rxdes_get_dma_addr(struct ftmac100_rxdes *rxdes) --{ -- return le32_to_cpu(rxdes->rxdes2); -+ priv->rx_buf = dma_allocate( NULL, RX_BUF_SIZE*RXDES_NUM, &(priv->rx_buf_dma), GFP_KERNEL ); -+ if (priv->rx_buf == NULL || (( (u32)priv->rx_buf & 3)!=0)) { -+ printk("Receive Ring Buffer allocation error\n"); -+ return -ENOMEM; -+ } -+#if FTMAC100_DEBUG > 2 -+ else -+ printk( KERN_INFO "* Allocated RX buf=%X, bus addr=%X, size=%d*%d=%d\n", -+ (unsigned)priv->rx_buf, (unsigned)priv->rx_buf_dma, -+ RX_BUF_SIZE, RXDES_NUM, RX_BUF_SIZE*RXDES_NUM ); -+#endif -+ -+ memset((void *)priv->rx_buf,0,sizeof(RX_BUF_SIZE)*RXDES_NUM); -+ -+ for (i=0; irx_descs[i].RXBUF_Size = RX_BUF_SIZE; -+ priv->rx_descs[i].EDOTR = 0; // not last descriptor -+ priv->rx_descs[i].RXBUF_BADR = priv->rx_buf_dma+RX_BUF_SIZE*i; -+ priv->rx_descs[i].VIR_RXBUF_BADR=(unsigned int)priv->rx_buf+RX_BUF_SIZE*i; -+ } -+ priv->rx_descs[RXDES_NUM-1].EDOTR = 1; // is last descriptor -+ -+ priv->tx_descs = dma_allocate( NULL, sizeof(TX_DESC)*TXDES_NUM, &(priv->tx_descs_dma), GFP_KERNEL ); -+ if (priv->tx_descs == NULL || (( (u32)priv->tx_descs & 0xf)!=0)) { -+ printk("Transmit Ring Buffer allocation error\n"); -+ return -ENOMEM; -+ } -+#if FTMAC100_DEBUG > 2 -+ else -+ printk( KERN_INFO "* Allocated TX descs=%X, bus addr=%X, size=%d*%d=%d\n", -+ (unsigned)priv->tx_descs, (unsigned)priv->tx_descs_dma, sizeof(TX_DESC),TXDES_NUM,sizeof(TX_DESC)*TXDES_NUM); -+#endif -+ memset((void *)priv->tx_descs,0,sizeof(TX_DESC)*TXDES_NUM); -+ -+ priv->tx_buf = dma_allocate( NULL, TX_BUF_SIZE*TXDES_NUM, &(priv->tx_buf_dma), GFP_KERNEL ); -+ if (priv->tx_buf == NULL || (( (u32)priv->tx_buf & 0x3)!=0)) { -+ printk("Transmit Ring Buffer allocation error\n"); -+ return -ENOMEM; -+ } -+#if FTMAC100_DEBUG > 2 -+ else -+ printk( KERN_INFO "* Allocated TX buf=%X, bus addr=%X, size=%d*%d=%d\n", -+ (unsigned)priv->tx_buf, (unsigned)priv->tx_buf_dma, -+ TX_BUF_SIZE, TXDES_NUM, TX_BUF_SIZE*TXDES_NUM ); -+#endif -+ -+ memset((void *)priv->tx_buf,0,sizeof(TX_BUF_SIZE)*TXDES_NUM); -+ -+ for (i=0; itx_descs[i].EDOTR = 0; // not last descriptor -+ priv->tx_descs[i].TXBUF_BADR=priv->tx_buf_dma+TX_BUF_SIZE*i; -+ priv->tx_descs[i].VIR_TXBUF_BADR=(unsigned int)priv->tx_buf+TX_BUF_SIZE*i; -+ } -+ priv->tx_descs[TXDES_NUM-1].EDOTR = 1; // is last descriptor -+ return 0; - } - - /* -- * rxdes3 is not used by hardware. We use it to keep track of page. -- * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). -+ * Function: ftmac100_poll( struct net_device *dev ) -+ * -+ * Purpose: -+ * poll interface callback function. - */ --static void ftmac100_rxdes_set_page(struct ftmac100_rxdes *rxdes, struct page *page) -+void ftmac100_poll(struct net_device *dev) - { -- rxdes->rxdes3 = (unsigned int)page; -+ disable_irq(dev->irq); -+ ftmac100_interrupt(dev->irq, dev); -+ enable_irq(dev->irq); - } - --static struct page *ftmac100_rxdes_get_page(struct ftmac100_rxdes *rxdes) --{ -- return (struct page *)rxdes->rxdes3; --} -- --/****************************************************************************** -- * internal functions (receive) -- *****************************************************************************/ --static int ftmac100_next_rx_pointer(int pointer) -+/* -+ * Function: ftmac100_setup( struct net_device *dev ) -+ * -+ * Purpose: -+ * Tests to see if the device 'dev' points to an ftmac100 chip. -+ * Returns a 0 on success -+ */ -+static const struct net_device_ops ftmac100_ops = { -+ .ndo_init = ftmac100_setup, -+ .ndo_open = ftmac100_open, -+ .ndo_stop = ftmac100_close, -+ .ndo_start_xmit = ftmac100_wait_to_send_packet, -+ .ndo_get_stats = ftmac100_query_statistics, -+ .ndo_tx_timeout = ftmac100_timeout, -+#ifdef HAVE_MULTICAST -+ .ndo_set_multicast_list = ftmac100_set_multicast_list, -+#endif -+ .ndo_set_mac_address = eth_mac_addr, -+#ifdef CONFIG_NET_POLL_CONTROLLER -+ .ndo_poll_controller = ftmac100_poll, -+#endif -+}; -+static int ftmac100_setup(struct net_device *dev) - { -- return (pointer + 1) & (RX_QUEUE_ENTRIES - 1); --} -+ int retval; -+ static unsigned version_printed = 0; -+ struct ftmac100_local *priv; -+ -+ if (version_printed++ == 0) -+ printk(KERN_INFO "%s", version); -+ -+ /* Now, print out the card info, in a short format.. */ -+ printk(KERN_INFO "%s: device at %#3x IRQ:%d NOWAIT:%d\n",dev->name, -+ (unsigned)dev->base_addr, dev->irq, dev->dma); -+ -+ /* Initialize priviate data */ -+ priv = (struct ftmac100_local *)netdev_priv(dev); -+ memset(priv, 0, sizeof(struct ftmac100_local)); -+ spin_lock_init(&priv->lock); -+ priv->maccr_val = FULLDUP_bit -+ | CRC_APD_bit -+ | MDC_SEL_bit -+ | RCV_EN_bit -+ | XMT_EN_bit -+ | RDMA_EN_bit -+ | XDMA_EN_bit ; -+ retval = ftmac100_ringbuf_alloc(dev,priv); -+ if (retval) -+ goto err_out; -+ -+ /* now, reset the chip, and put it into a known state */ -+ retval = ftmac100_reset( dev ); -+ if (retval) { -+ printk( "%s: unable to reset.\n", dev->name ); -+ goto err_out; -+ } -+ -+ /* Fill in the fields of the device structure with ethernet values. */ -+ ether_setup(dev); -+ -+ /* Grab the IRQ */ -+ retval = request_irq(dev->irq, &ftmac100_interrupt, IRQF_DISABLED, dev->name, dev); -+ if (retval) { -+ printk("%s: unable to get IRQ %d (irqval=%d).\n", dev->name, dev->irq, retval); -+ goto err_out; -+ } -+ -+#if 0 -+ if ((proc_ftmac100 = create_proc_entry( "ftmac100", 0, 0 ))) { -+ proc_ftmac100->read_proc = ftmac100_read_proc; -+ proc_ftmac100->data = dev; -+ proc_ftmac100->owner = THIS_MODULE; -+ } -+#endif - --static void ftmac100_rx_pointer_advance(struct ftmac100 *priv) --{ -- priv->rx_pointer = ftmac100_next_rx_pointer(priv->rx_pointer); --} -+ return 0; - --static struct ftmac100_rxdes *ftmac100_current_rxdes(struct ftmac100 *priv) --{ -- return &priv->descs->rxdes[priv->rx_pointer]; -+err_out: -+ dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma ); -+ dma_free_coherent( NULL, RX_BUF_SIZE*RXDES_NUM, (void*)priv->rx_buf, (dma_addr_t)priv->rx_buf_dma ); -+ dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma ); -+ dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma ); -+ priv->rx_descs = NULL; priv->rx_descs_dma = 0; -+ priv->rx_buf = NULL; priv->rx_buf_dma = 0; -+ priv->tx_descs = NULL; priv->tx_descs_dma = 0; -+ priv->tx_buf = NULL; priv->tx_buf_dma = 0; -+ return retval; - } - --static struct ftmac100_rxdes * --ftmac100_rx_locate_first_segment(struct ftmac100 *priv) --{ -- struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv); - -- while (!ftmac100_rxdes_owned_by_dma(rxdes)) { -- if (ftmac100_rxdes_first_segment(rxdes)) -- return rxdes; -+#if FTMAC100_DEBUG > 2 -+static void print_packet( unsigned char * buf, int length ) -+{ -+#if FTMAC100_DEBUG > 3 -+ int i; -+ int remainder; -+ int lines; -+#endif - -- ftmac100_rxdes_set_dma_own(rxdes); -- ftmac100_rx_pointer_advance(priv); -- rxdes = ftmac100_current_rxdes(priv); -- } -+// printk("Packet of length %d \n", length ); - -- return NULL; -+#if FTMAC100_DEBUG > 3 -+ lines = length >> 4; -+ remainder = length & 15; -+ -+ for ( i = 0; i < lines ; i ++ ) { -+ int cur; -+ for ( cur = 0; cur < 8; cur ++ ) { -+ unsigned char a, b; -+ a = *(buf ++ ); -+ b = *(buf ++ ); -+ printk("%02x%02x ", a, b ); -+ } -+ printk("\n"); -+ } -+ for ( i = 0; i < remainder/2 ; i++ ) { -+ unsigned char a, b; -+ -+ a = *(buf ++ ); -+ b = *(buf ++ ); -+ printk("%02x%02x ", a, b ); -+ } -+ printk("\n"); -+#endif - } -+#endif - --static bool ftmac100_rx_packet_error(struct ftmac100 *priv, -- struct ftmac100_rxdes *rxdes) --{ -- struct net_device *netdev = priv->netdev; -- bool error = false; -- -- if (unlikely(ftmac100_rxdes_rx_error(rxdes))) { -- if (net_ratelimit()) -- netdev_info(netdev, "rx err\n"); -- -- netdev->stats.rx_errors++; -- error = true; -- } -- -- if (unlikely(ftmac100_rxdes_crc_error(rxdes))) { -- if (net_ratelimit()) -- netdev_info(netdev, "rx crc err\n"); -- -- netdev->stats.rx_crc_errors++; -- error = true; -- } -- -- if (unlikely(ftmac100_rxdes_frame_too_long(rxdes))) { -- if (net_ratelimit()) -- netdev_info(netdev, "rx frame too long\n"); -- -- netdev->stats.rx_length_errors++; -- error = true; -- } else if (unlikely(ftmac100_rxdes_runt(rxdes))) { -- if (net_ratelimit()) -- netdev_info(netdev, "rx runt\n"); -- -- netdev->stats.rx_length_errors++; -- error = true; -- } else if (unlikely(ftmac100_rxdes_odd_nibble(rxdes))) { -- if (net_ratelimit()) -- netdev_info(netdev, "rx odd nibble\n"); -- -- netdev->stats.rx_length_errors++; -- error = true; -- } -- -- return error; --} - --static void ftmac100_rx_drop_packet(struct ftmac100 *priv) -+/* -+ * Open and Initialize the board -+ * -+ * Set up everything, reset the card, etc .. -+ * -+ */ -+static int ftmac100_open(struct net_device *dev) - { -- struct net_device *netdev = priv->netdev; -- struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv); -- bool done = false; -- -- if (net_ratelimit()) -- netdev_dbg(netdev, "drop packet %p\n", rxdes); -+ int retval = 0; -+ PRINTK("+%s:ftmac100_open\n", dev->name); - -- do { -- if (ftmac100_rxdes_last_segment(rxdes)) -- done = true; -+ //netif_start_queue(dev); - -- ftmac100_rxdes_set_dma_own(rxdes); -- ftmac100_rx_pointer_advance(priv); -- rxdes = ftmac100_current_rxdes(priv); -- } while (!done && !ftmac100_rxdes_owned_by_dma(rxdes)); -- -- netdev->stats.rx_dropped++; -+ /* reset the hardware */ -+ ftmac100_reset( dev ); -+ retval = ftmac100_reset( dev ); -+ if (retval) { -+ printk( "%s: unable to reset.\n", dev->name ); -+ retval = -ENODEV; -+ } else { -+ ftmac100_enable( dev ); -+ -+ /* Configure the PHY */ -+ ftmac100_phy_configure(dev); -+ -+ netif_start_queue(dev); -+ -+ PRINTK("+%s:ftmac100_open DONE\n", dev->name); -+ } -+ -+ return retval; - } - --static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed) --{ -- struct net_device *netdev = priv->netdev; -- struct ftmac100_rxdes *rxdes; -- struct sk_buff *skb; -- struct page *page; -- dma_addr_t map; -- int length; - -- rxdes = ftmac100_rx_locate_first_segment(priv); -- if (!rxdes) -- return false; -- -- if (unlikely(ftmac100_rx_packet_error(priv, rxdes))) { -- ftmac100_rx_drop_packet(priv); -- return true; -- } -- -- /* -- * It is impossible to get multi-segment packets -- * because we always provide big enough receive buffers. -- */ -- if (unlikely(!ftmac100_rxdes_last_segment(rxdes))) -- BUG(); -- -- /* start processing */ -- skb = netdev_alloc_skb_ip_align(netdev, 128); -- if (unlikely(!skb)) { -- if (net_ratelimit()) -- netdev_err(netdev, "rx skb alloc failed\n"); -- -- ftmac100_rx_drop_packet(priv); -- return true; -- } -- -- if (unlikely(ftmac100_rxdes_multicast(rxdes))) -- netdev->stats.multicast++; -- -- map = ftmac100_rxdes_get_dma_addr(rxdes); -- dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); -- -- length = ftmac100_rxdes_frame_length(rxdes); -- page = ftmac100_rxdes_get_page(rxdes); -- skb_fill_page_desc(skb, 0, page, 0, length); -- skb->len += length; -- skb->data_len += length; -- -- /* page might be freed in __pskb_pull_tail() */ -- if (length > 64) -- skb->truesize += PAGE_SIZE; -- __pskb_pull_tail(skb, min(length, 64)); -- -- ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC); -- -- ftmac100_rx_pointer_advance(priv); -- -- skb->protocol = eth_type_trans(skb, netdev); -- -- netdev->stats.rx_packets++; -- netdev->stats.rx_bytes += skb->len; -+/* -+ * Called by the kernel to send a packet out into the void -+ * of the net. This routine is largely based on -+ * skeleton.c, from Becker. -+ * -+ */ -+static void ftmac100_timeout (struct net_device *dev) -+{ -+ /* If we get here, some higher level has decided we are broken. -+ There should really be a "kick me" function call instead. */ -+ printk(KERN_WARNING "%s: transmit timed out?\n",dev->name); - -- /* push packet to protocol stack */ -- netif_receive_skb(skb); -+ //printk("+ftmac100_timeout\n"); - -- (*processed)++; -- return true; -+ ftmac100_reset( dev ); -+ ftmac100_enable( dev ); -+ ftmac100_phy_configure(dev); -+ netif_wake_queue(dev); -+ dev->trans_start = jiffies; - } - --/****************************************************************************** -- * internal functions (transmit descriptor) -- *****************************************************************************/ --static void ftmac100_txdes_reset(struct ftmac100_txdes *txdes) -+#if ZERO_COPY -+/* -+ * Free transmitted skb buffer when it's safe. -+ */ -+static void ftmac100_free_tx (struct net_device *dev, int irq) - { -- /* clear all except end of ring bit */ -- txdes->txdes0 = 0; -- txdes->txdes1 &= cpu_to_le32(FTMAC100_TXDES1_EDOTR); -- txdes->txdes2 = 0; -- txdes->txdes3 = 0; --} -+ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); -+ //volatile TX_DESC *cur_desc; -+ int entry = priv->old_tx & (TXDES_NUM-1); -+ -+ //enter spinlock -+ if (!irq) -+ spin_lock(&priv->lock); -+ -+ /* Free used tx skbuffs */ -+ while (entry != priv->tx_idx) { -+ struct sk_buff *skb; -+ -+ skb = priv->tx_skbuff[entry]; -+ if(skb) { -+ dev_kfree_skb_any (skb); -+ priv->tx_skbuff[entry] = 0; -+ } - --static bool ftmac100_txdes_owned_by_dma(struct ftmac100_txdes *txdes) --{ -- return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN); --} -+ entry = (entry + 1) & (TXDES_NUM-1); -+ } - --static void ftmac100_txdes_set_dma_own(struct ftmac100_txdes *txdes) --{ -- /* -- * Make sure dma own bit will not be set before any other -- * descriptor fields. -- */ -- wmb(); -- txdes->txdes0 |= cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN); --} -+ if (!irq) -+ spin_unlock(&priv->lock); -+ //exit spinloc - --static bool ftmac100_txdes_excessive_collision(struct ftmac100_txdes *txdes) --{ -- return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_EXSCOL); -+ priv->old_tx = entry; -+ netif_wake_queue (dev); - } -+#endif - --static bool ftmac100_txdes_late_collision(struct ftmac100_txdes *txdes) --{ -- return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_LATECOL); --} -+/* -+ . -+ . This is the main routine of the driver, to handle the net_device when -+ . it needs some attention. -+ . -+ . So: -+ . first, save state of the chipset -+ . branch off into routines to handle each case, and acknowledge -+ . each to the interrupt register -+ . and finally restore state. -+ . -+ */ - --static void ftmac100_txdes_set_end_of_ring(struct ftmac100_txdes *txdes) --{ -- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_EDOTR); --} -+#if FTMAC100_DEBUG > 2 - --static void ftmac100_txdes_set_first_segment(struct ftmac100_txdes *txdes) -+static void dump_intc(void) - { -- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_FTS); -+ printk( " INTC[0] IRQSRC=%08X,MASK=%08X,MOD=%08X,LEV=%08X,STAT=%08X\n", -+ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0)), -+ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x4)), -+ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0xc)), -+ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x10)), -+ *((volatile unsigned*)(INTC_FTINTC010_VA_BASE+0x14)) ); -+ printk( " INTC[1] IRQSRC=%08X,MASK=%08X,MOD=%08X,LEV=%08X,STAT=%08X\n", -+ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0)), -+ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x4)), -+ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0xc)), -+ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x10)), -+ *((volatile unsigned*)(INTC_FTINTC010_1_VA_BASE+0x14)) ); - } -+#else -+#define dump_intc() -+#endif - --static void ftmac100_txdes_set_last_segment(struct ftmac100_txdes *txdes) -+#if FTMAC100_DEBUG > 2 -+static void show_intstatus(unsigned char status) - { -- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_LTS); -+ static int count = 0; -+ if (status & PHYSTS_CHG_bit) -+ printk( "[%d]%s ", count, "PHYSTS_CHG" ); -+ if (status & AHB_ERR_bit) -+ printk( "[%d]%s ", count, "AHB_ERR" ); -+ if (status & RPKT_LOST_bit) -+ printk( "[%d]%s ", count, "RPKT_LOST" ); -+ if (status & RPKT_SAV_bit) -+ printk( "[%d]%s ", count, "RPKT_SAV" ); -+ if (status & XPKT_LOST_bit) -+ printk( "[%d]%s ", count, "XPKT_LOST" ); -+ if (status & XPKT_OK_bit) -+ printk( "[%d]%s ", count, "XPKT_OK" ); -+ if (status & NOTXBUF_bit) -+ printk( "[%d]%s ", count, "NOTXBUF" ); -+ if (status & XPKT_FINISH_bit) -+ printk( "[%d]%s ", count, "XPKT_FINISH" ); -+ if (status & NORXBUF_bit) -+ printk( "[%d]%s ", count, "NORXBUF" ); -+ if (status & RPKT_FINISH_bit) -+ printk( "[%d]%s ", count, "RPKT_FINISH" ); -+ if (status & ~(PHYSTS_CHG_bit | AHB_ERR_bit | RPKT_LOST_bit | RPKT_SAV_bit -+ | XPKT_LOST_bit | XPKT_OK_bit | NOTXBUF_bit | XPKT_FINISH_bit -+ | NORXBUF_bit | RPKT_FINISH_bit)) -+ printk( "[%d]%s ", count, "" ); -+ count++; - } -+#else -+#define show_intstatus(x) -+#endif -+ - --static void ftmac100_txdes_set_txint(struct ftmac100_txdes *txdes) -+/* -+ * The interrupt handler -+ */ -+static irqreturn_t ftmac100_interrupt(int irq, void * dev_id) - { -- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXIC); --} -+ struct net_device *dev = dev_id; -+ unsigned int ioaddr = dev->base_addr; -+ unsigned status; // interrupt status -+ unsigned char mask; // interrupt mask -+ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); -+ unsigned long flags; -+ -+ spin_lock_irqsave(&priv->lock,flags); // Luke 08/18/2005 ins -+ PRINTK(KERN_INFO "+ftmac100_interrupt\n"); -+ dump_intc(); -+ -+ if (dev == NULL||priv == NULL) { -+ printk(KERN_WARNING "%s: irq %d for unknown device.\n", "ftmac100_interrupt", irq); -+ return IRQ_HANDLED; -+ } -+ -+ /* read the interrupt status register */ -+ mask = inl( ioaddr + IMR_REG ); -+ -+ /* read the status flag, and mask it */ -+ status = inl( ioaddr + ISR_REG ) & mask; -+ -+ show_intstatus(status); -+ -+ if ( status & RPKT_FINISH_bit ) -+ ftmac100_rcv(dev); -+ -+ if (status & NORXBUF_bit) { -+ //printk("<0x%x:NORXBUF>",status); -+ outl( mask & ~NORXBUF_bit, ioaddr + IMR_REG); -+ trans_busy = 1; -+ -+#if ENABLE_BOTTOM_HALF -+ priv->rcv_tq.sync = 0; -+ priv->rcv_tq.routine=ftmac100_rcv; -+ priv->rcv_tq.data = dev; -+ queue_task(&priv->rcv_tq, &tq_timer); -+ //queue_task(&priv->rcv_tq, &tq_immediate); -+#else -+ ftmac100_rcv( dev ); -+#endif -+ } -+ -+ if (status & AHB_ERR_bit) -+ printk("<0x%x:AHB_ERR>",status); -+ -+ if (status & XPKT_FINISH_bit) -+ printk( "[XPKT_FINISH]" ); -+ -+ /* -+ if (status & PHYSTS_CHG_bit) { -+ } -+ */ -+ if (status & XPKT_OK_bit) { -+#if ZERO_COPY -+ ftmac100_free_tx(dev,1); -+#endif -+ } -+ /* -+ if (status & NOTXBUF_bit) { -+ } -+ */ -+ -+ if (status & RPKT_LOST_bit) -+ priv->stats.rx_errors++; -+ -+ if (status & XPKT_LOST_bit) { -+#if ZERO_COPY -+ ftmac100_free_tx(dev,1); -+#endif -+ priv->stats.tx_errors++; -+ } -+ -+ PRINTK(KERN_INFO "+ftmac100_interrupt DONE\n"); -+ dump_intc(); -+ PRINTK(KERN_INFO "\n"); -+ spin_unlock_irqrestore(&priv->lock,flags); // Luke 08/18/2005 ins - --static void ftmac100_txdes_set_buffer_size(struct ftmac100_txdes *txdes, -- unsigned int len) --{ -- txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXBUF_SIZE(len)); -+ return IRQ_HANDLED; - } - --static void ftmac100_txdes_set_dma_addr(struct ftmac100_txdes *txdes, -- dma_addr_t addr) --{ -- txdes->txdes2 = cpu_to_le32(addr); --} - --static dma_addr_t ftmac100_txdes_get_dma_addr(struct ftmac100_txdes *txdes) --{ -- return le32_to_cpu(txdes->txdes2); --} - - /* -- * txdes3 is not used by hardware. We use it to keep track of socket buffer. -- * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu(). -+ . ftmac100_rcv - receive a packet from the card -+ . -+ . There is ( at least ) a packet waiting to be read from -+ . chip-memory. -+ . -+ . o Read the status -+ . o If an error, record it -+ . o otherwise, read in the packet - */ --static void ftmac100_txdes_set_skb(struct ftmac100_txdes *txdes, struct sk_buff *skb) --{ -- txdes->txdes3 = (unsigned int)skb; --} - --static struct sk_buff *ftmac100_txdes_get_skb(struct ftmac100_txdes *txdes) -+static void ftmac100_rcv(void *devp) - { -- return (struct sk_buff *)txdes->txdes3; -+ struct net_device *dev=(struct net_device *)devp; -+ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); -+ unsigned int ioaddr=dev->base_addr; -+ int packet_length; -+ int rcv_cnt; -+ volatile RX_DESC *cur_desc; -+ int cpy_length; -+ int cur_idx; -+ int seg_length; -+ int have_package; -+ int have_frs; -+ int start_idx; -+ -+ struct sk_buff * skb; -+ unsigned char * data; -+ -+ PRINTK("+ ftmac100_rcv\n"); -+ -+ start_idx = priv->rx_idx; -+ -+ for (rcv_cnt=0; rcv_cnt<8 ; ++rcv_cnt) { -+ packet_length = 0; -+ cur_idx = priv->rx_idx; -+ -+ have_package = 0; -+ have_frs = 0; -+ for (; (cur_desc = &priv->rx_descs[priv->rx_idx])->RXDMA_OWN==0; ) { -+ have_package = 1; -+ priv->rx_idx = (priv->rx_idx+1) & (RXDES_NUM-1); -+ if (cur_desc->FRS) { -+ have_frs = 1; -+ if (cur_desc->RX_ERR || cur_desc->CRC_ERR || cur_desc->FTL -+ || cur_desc->RUNT || cur_desc->RX_ODD_NB) { -+ priv->stats.rx_errors++; // error frame.... -+ break; -+ } -+ if (cur_desc->MULTICAST) -+ priv->stats.multicast++; -+ packet_length = cur_desc->ReceiveFrameLength; // normal frame -+ } -+ if ( cur_desc->LRS ) // packet's last frame -+ break; -+ } -+ if (have_package==0) -+ goto done; -+ if (have_frs == 0) -+ priv->stats.rx_over_errors++; -+ -+ if (packet_length>0) { -+ // Allocate enough memory for entire receive frame, to be safe -+ skb = dev_alloc_skb( packet_length + 2 ); -+ -+ if ( skb == NULL ) { -+ printk(KERN_NOTICE "%s: Low memory, packet dropped.\n", dev->name); -+ priv->stats.rx_dropped++; -+ goto done; -+ } -+ -+ skb_reserve( skb, 2 ); /* 16 bit alignment */ -+ skb->dev = dev; -+ -+ data = skb_put( skb, packet_length ); -+ cpy_length = 0; -+ for (; cur_idx!=priv->rx_idx; cur_idx = (cur_idx+1) & (RXDES_NUM-1)) { -+ seg_length = min(packet_length - cpy_length, RX_BUF_SIZE); -+ memcpy(data+cpy_length, (char *)priv->rx_descs[cur_idx].VIR_RXBUF_BADR, seg_length); -+ cpy_length += seg_length; -+ } -+ -+ skb->protocol = eth_type_trans(skb, dev); -+ netif_rx(skb); -+ dev->last_rx = jiffies; -+ priv->stats.rx_packets++; -+ priv->stats.rx_bytes += skb->len; -+ } -+ } -+ -+done: -+ if (start_idx != priv->rx_idx) { -+ for (cur_idx = (start_idx+1)%RXDES_NUM; cur_idx != priv->rx_idx; cur_idx = (cur_idx+1)%RXDES_NUM) { -+ priv->rx_descs[cur_idx].RXDMA_OWN = 1; -+ } -+ priv->rx_descs[start_idx].RXDMA_OWN = 1; -+ } -+ if (trans_busy == 1) { -+ outl( priv->maccr_val, ioaddr + MACCR_REG ); -+ outl( inl(ioaddr + IMR_REG) | NORXBUF_bit, ioaddr + IMR_REG); -+ } -+ -+ PRINTK("+ ftmac100_rcv DONE\n"); -+ -+ return; - } - --/****************************************************************************** -- * internal functions (transmit) -- *****************************************************************************/ --static int ftmac100_next_tx_pointer(int pointer) -+/* -+ . ftmac100_close -+ . -+ . this makes the board clean up everything that it can -+ . and not talk to the outside world. Caused by -+ . an 'ifconfig ethX down' -+ . -+ */ -+static int ftmac100_close(struct net_device *dev) - { -- return (pointer + 1) & (TX_QUEUE_ENTRIES - 1); --} -+ //printk("+ftmac100_close\n"); - --static void ftmac100_tx_pointer_advance(struct ftmac100 *priv) --{ -- priv->tx_pointer = ftmac100_next_tx_pointer(priv->tx_pointer); -+ netif_stop_queue(dev); -+ -+ ftmac100_shutdown( dev->base_addr ); -+#if ZERO_COPY -+ ftmac100_free_tx(dev,0); -+#endif -+ return 0; - } - --static void ftmac100_tx_clean_pointer_advance(struct ftmac100 *priv) -+/* -+ . Get the current statistics. -+ . This may be called with the card open or closed. -+ */ -+static struct net_device_stats* ftmac100_query_statistics(struct net_device *dev) - { -- priv->tx_clean_pointer = ftmac100_next_tx_pointer(priv->tx_clean_pointer); --} -+ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); - --static struct ftmac100_txdes *ftmac100_current_txdes(struct ftmac100 *priv) --{ -- return &priv->descs->txdes[priv->tx_pointer]; --} -+ PRINTK("+ftmac100_query_statistics\n"); - --static struct ftmac100_txdes *ftmac100_current_clean_txdes(struct ftmac100 *priv) --{ -- return &priv->descs->txdes[priv->tx_clean_pointer]; -+ return &priv->stats; - } - --static bool ftmac100_tx_complete_packet(struct ftmac100 *priv) --{ -- struct net_device *netdev = priv->netdev; -- struct ftmac100_txdes *txdes; -- struct sk_buff *skb; -- dma_addr_t map; -- -- if (priv->tx_pending == 0) -- return false; - -- txdes = ftmac100_current_clean_txdes(priv); -- -- if (ftmac100_txdes_owned_by_dma(txdes)) -- return false; -- -- skb = ftmac100_txdes_get_skb(txdes); -- map = ftmac100_txdes_get_dma_addr(txdes); -- -- if (unlikely(ftmac100_txdes_excessive_collision(txdes) || -- ftmac100_txdes_late_collision(txdes))) { -- /* -- * packet transmitted to ethernet lost due to late collision -- * or excessive collision -- */ -- netdev->stats.tx_aborted_errors++; -- } else { -- netdev->stats.tx_packets++; -- netdev->stats.tx_bytes += skb->len; -- } -+#ifdef HAVE_MULTICAST - -- dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); -- dev_kfree_skb(skb); -- -- ftmac100_txdes_reset(txdes); -- -- ftmac100_tx_clean_pointer_advance(priv); -- -- spin_lock(&priv->tx_lock); -- priv->tx_pending--; -- spin_unlock(&priv->tx_lock); -- netif_wake_queue(netdev); -- -- return true; --} -+/* -+ . Function: ftmac100_setmulticast( unsigned int ioaddr, int count, dev_mc_list * adds ) -+ . Purpose: -+ . This sets the internal hardware table to filter out unwanted multicast -+ . packets before they take up memory. -+ */ - --static void ftmac100_tx_complete(struct ftmac100 *priv) -+static void ftmac100_setmulticast( unsigned int ioaddr, int count, struct dev_mc_list * addrs ) - { -- while (ftmac100_tx_complete_packet(priv)) -- ; -+ struct dev_mc_list * cur_addr; -+ int crc_val; -+ -+ //printk("+ftmac100_setmulticast\n"); -+ -+ for (cur_addr = addrs ; cur_addr!=NULL ; cur_addr = cur_addr->next ) { -+ if ( !( *cur_addr->dmi_addr & 1 ) ) -+ continue; -+ crc_val = crc32( cur_addr->dmi_addr, 6 ); -+ crc_val = (crc_val>>26)&0x3f; // ¨ú MSB 6 bit -+ if (crc_val >= 32) -+ outl(inl(ioaddr+MAHT1_REG) | (1UL<<(crc_val-32)), ioaddr+MAHT1_REG); -+ else -+ outl(inl(ioaddr+MAHT0_REG) | (1UL<netdev; -- struct ftmac100_txdes *txdes; -- unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len; -- -- txdes = ftmac100_current_txdes(priv); -- ftmac100_tx_pointer_advance(priv); -- -- /* setup TX descriptor */ -- ftmac100_txdes_set_skb(txdes, skb); -- ftmac100_txdes_set_dma_addr(txdes, map); -- -- ftmac100_txdes_set_first_segment(txdes); -- ftmac100_txdes_set_last_segment(txdes); -- ftmac100_txdes_set_txint(txdes); -- ftmac100_txdes_set_buffer_size(txdes, len); - -- spin_lock(&priv->tx_lock); -- priv->tx_pending++; -- if (priv->tx_pending == TX_QUEUE_ENTRIES) -- netif_stop_queue(netdev); -- -- /* start transmit */ -- ftmac100_txdes_set_dma_own(txdes); -- spin_unlock(&priv->tx_lock); -+/* -+ . ftmac100_set_multicast_list -+ . -+ . This routine will, depending on the values passed to it, -+ . either make it accept multicast packets, go into -+ . promiscuous mode ( for TCPDUMP and cousins ) or accept -+ . a select set of multicast packets -+*/ -+static void ftmac100_set_multicast_list(struct net_device *dev) -+{ -+ unsigned int ioaddr = dev->base_addr; -+ struct ftmac100_local *priv = (struct ftmac100_local *)netdev_priv(dev); -+ -+ //printk("+ftmac100_set_multicast_list\n"); -+ -+ if (dev->flags & IFF_PROMISC) -+ priv->maccr_val |= RCV_ALL_bit; -+ else -+ priv->maccr_val &= ~RCV_ALL_bit; -+ -+ if ( !(dev->flags & IFF_ALLMULTI) ) -+ priv->maccr_val |= RX_MULTIPKT_bit; -+ else -+ priv->maccr_val &= ~RX_MULTIPKT_bit; -+ -+ if (dev->mc_count) { -+ priv->maccr_val |= HT_MULTI_EN_bit; -+ ftmac100_setmulticast( ioaddr, dev->mc_count, dev->mc_list ); -+ } -+ else -+ priv->maccr_val &= ~HT_MULTI_EN_bit; - -- ftmac100_txdma_start_polling(priv); -- return NETDEV_TX_OK; -+ outl( priv->maccr_val, ioaddr + MACCR_REG ); - } -+#endif - --/****************************************************************************** -- * internal functions (buffer) -- *****************************************************************************/ --static int ftmac100_alloc_rx_page(struct ftmac100 *priv, -- struct ftmac100_rxdes *rxdes, gfp_t gfp) --{ -- struct net_device *netdev = priv->netdev; -- struct page *page; -- dma_addr_t map; -- -- page = alloc_page(gfp); -- if (!page) { -- if (net_ratelimit()) -- netdev_err(netdev, "failed to allocate rx page\n"); -- return -ENOMEM; -- } -- -- map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE); -- if (unlikely(dma_mapping_error(priv->dev, map))) { -- if (net_ratelimit()) -- netdev_err(netdev, "failed to map rx page\n"); -- __free_page(page); -- return -ENOMEM; -- } -- -- ftmac100_rxdes_set_page(rxdes, page); -- ftmac100_rxdes_set_dma_addr(rxdes, map); -- ftmac100_rxdes_set_buffer_size(rxdes, RX_BUF_SIZE); -- ftmac100_rxdes_set_dma_own(rxdes); -- return 0; --} -+/* -+ * Module initialization function -+ */ - --static void ftmac100_free_buffers(struct ftmac100 *priv) -+static int ftmac100_probe(struct platform_device *pdev) - { -- int i; -+ int result,thisresult; -+ struct net_device *dev; -+ struct resource *iores; - -- for (i = 0; i < RX_QUEUE_ENTRIES; i++) { -- struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; -- struct page *page = ftmac100_rxdes_get_page(rxdes); -- dma_addr_t map = ftmac100_rxdes_get_dma_addr(rxdes); -+ PRINTK("+init_module\n"); - -- if (!page) -- continue; -+ result = -ENODEV; - -- dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); -- __free_page(page); -+ dev = alloc_etherdev(sizeof(struct ftmac100_local)); -+ if (!dev) { -+ printk(KERN_ERR "Fail allocating ethernet device"); -+ return -ENODEV; - } -- -- for (i = 0; i < TX_QUEUE_ENTRIES; i++) { -- struct ftmac100_txdes *txdes = &priv->descs->txdes[i]; -- struct sk_buff *skb = ftmac100_txdes_get_skb(txdes); -- dma_addr_t map = ftmac100_txdes_get_dma_addr(txdes); -- -- if (!skb) -- continue; -- -- dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE); -- dev_kfree_skb(skb); -+ iores = platform_get_resource(pdev, IORESOURCE_IO, 0); -+ /* Copy the parameters from the platform specification */ -+ dev->base_addr = iores->start; -+ dev->irq = platform_get_irq(pdev, 0); -+ dev->netdev_ops = &ftmac100_ops; -+ -+ //dev->dma = nowait; // Use DMA field for nowait -+ /* Setup initial mac address */ -+ auto_get_mac(pdev->id,dev->dev_addr); -+ -+ if ((thisresult = register_netdev(dev)) != 0) { -+ free_irq( dev->irq, dev ); -+ free_netdev(dev); -+ } else { -+ platform_set_drvdata(pdev, dev); - } -+ if (thisresult == 0) // any of the devices initialized, run -+ result = 0; - -- dma_free_coherent(priv->dev, sizeof(struct ftmac100_descs), -- priv->descs, priv->descs_dma_addr); -+ return result; - } - --static int ftmac100_alloc_buffers(struct ftmac100 *priv) --{ -- int i; -- -- priv->descs = dma_alloc_coherent(priv->dev, sizeof(struct ftmac100_descs), -- &priv->descs_dma_addr, GFP_KERNEL); -- if (!priv->descs) -- return -ENOMEM; -- -- memset(priv->descs, 0, sizeof(struct ftmac100_descs)); -- -- /* initialize RX ring */ -- ftmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]); -- -- for (i = 0; i < RX_QUEUE_ENTRIES; i++) { -- struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i]; -- -- if (ftmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL)) -- goto err; -- } -- -- /* initialize TX ring */ -- ftmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]); -- return 0; -- --err: -- ftmac100_free_buffers(priv); -- return -ENOMEM; --} - --/****************************************************************************** -- * struct mii_if_info functions -- *****************************************************************************/ --static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg) -+/* -+ * Cleanup when module is removed with rmmod -+ */ -+ -+static int ftmac100_remove(struct platform_device *pdev) - { -- struct ftmac100 *priv = netdev_priv(netdev); -- unsigned int phycr; -- int i; -- -- phycr = FTMAC100_PHYCR_PHYAD(phy_id) | -- FTMAC100_PHYCR_REGAD(reg) | -- FTMAC100_PHYCR_MIIRD; -- -- iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR); -- -- for (i = 0; i < 10; i++) { -- phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR); -- -- if ((phycr & FTMAC100_PHYCR_MIIRD) == 0) -- return phycr & FTMAC100_PHYCR_MIIRDATA; -- -- udelay(100); -- } -- -- netdev_err(netdev, "mdio read timed out\n"); -+ struct net_device *dev; -+ struct ftmac100_local *priv; -+ PRINTK("+cleanup_module\n"); -+ -+ dev = platform_get_drvdata(pdev); -+ -+ priv = (struct ftmac100_local *)netdev_priv(dev); -+ if (priv->rx_descs) -+ dma_free_coherent( NULL, sizeof(RX_DESC)*RXDES_NUM, (void*)priv->rx_descs, (dma_addr_t)priv->rx_descs_dma ); -+ if (priv->rx_buf) -+ dma_free_coherent( NULL, RX_BUF_SIZE*RXDES_NUM, (void*)priv->rx_buf, (dma_addr_t)priv->rx_buf_dma ); -+ if (priv->tx_descs) -+ dma_free_coherent( NULL, sizeof(TX_DESC)*TXDES_NUM, (void*)priv->tx_descs, (dma_addr_t)priv->tx_descs_dma ); -+ if (priv->tx_buf) -+ dma_free_coherent( NULL, TX_BUF_SIZE*TXDES_NUM, (void*)priv->tx_buf, (dma_addr_t)priv->tx_buf_dma ); -+ priv->rx_descs = NULL; priv->rx_descs_dma = 0; -+ priv->rx_buf = NULL; priv->rx_buf_dma = 0; -+ priv->tx_descs = NULL; priv->tx_descs_dma = 0; -+ priv->tx_buf = NULL; priv->tx_buf_dma = 0; -+ -+ /* No need to check MOD_IN_USE, as sys_delete_module() checks. */ -+ unregister_netdev(dev); -+ -+ free_irq(dev->irq, dev); -+ //TODO: where is the request_region ? -+ //release_region(devFMAC.base_addr, SMC_IO_EXTENT); -+ free_netdev(dev); - return 0; - } - --static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg, -- int data) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- unsigned int phycr; -- int i; -- -- phycr = FTMAC100_PHYCR_PHYAD(phy_id) | -- FTMAC100_PHYCR_REGAD(reg) | -- FTMAC100_PHYCR_MIIWR; -- -- data = FTMAC100_PHYWDATA_MIIWDATA(data); -- -- iowrite32(data, priv->base + FTMAC100_OFFSET_PHYWDATA); -- iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR); -- -- for (i = 0; i < 10; i++) { -- phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR); -- -- if ((phycr & FTMAC100_PHYCR_MIIWR) == 0) -- return; -- -- udelay(100); -- } -- -- netdev_err(netdev, "mdio write timed out\n"); --} -- --/****************************************************************************** -- * struct ethtool_ops functions -- *****************************************************************************/ --static void ftmac100_get_drvinfo(struct net_device *netdev, -- struct ethtool_drvinfo *info) --{ -- strcpy(info->driver, DRV_NAME); -- strcpy(info->version, DRV_VERSION); -- strcpy(info->bus_info, dev_name(&netdev->dev)); --} -- --static int ftmac100_get_settings(struct net_device *netdev, struct ethtool_cmd *cmd) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- return mii_ethtool_gset(&priv->mii, cmd); --} -- --static int ftmac100_set_settings(struct net_device *netdev, struct ethtool_cmd *cmd) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- return mii_ethtool_sset(&priv->mii, cmd); --} -- --static int ftmac100_nway_reset(struct net_device *netdev) -+static int ftmac100_suspend(struct platform_device *pdev, pm_message_t state) - { -- struct ftmac100 *priv = netdev_priv(netdev); -- return mii_nway_restart(&priv->mii); --} -- --static u32 ftmac100_get_link(struct net_device *netdev) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- return mii_link_ok(&priv->mii); --} -- --static const struct ethtool_ops ftmac100_ethtool_ops = { -- .set_settings = ftmac100_set_settings, -- .get_settings = ftmac100_get_settings, -- .get_drvinfo = ftmac100_get_drvinfo, -- .nway_reset = ftmac100_nway_reset, -- .get_link = ftmac100_get_link, --}; -- --/****************************************************************************** -- * interrupt handler -- *****************************************************************************/ --static irqreturn_t ftmac100_interrupt(int irq, void *dev_id) --{ -- struct net_device *netdev = dev_id; -- struct ftmac100 *priv = netdev_priv(netdev); -- -- if (likely(netif_running(netdev))) { -- /* Disable interrupts for polling */ -- ftmac100_disable_all_int(priv); -- napi_schedule(&priv->napi); -- } -- -- return IRQ_HANDLED; --} -- --/****************************************************************************** -- * struct napi_struct functions -- *****************************************************************************/ --static int ftmac100_poll(struct napi_struct *napi, int budget) --{ -- struct ftmac100 *priv = container_of(napi, struct ftmac100, napi); -- struct net_device *netdev = priv->netdev; -- unsigned int status; -- bool completed = true; -- int rx = 0; -- -- status = ioread32(priv->base + FTMAC100_OFFSET_ISR); -- -- if (status & (FTMAC100_INT_RPKT_FINISH | FTMAC100_INT_NORXBUF)) { -- /* -- * FTMAC100_INT_RPKT_FINISH: -- * RX DMA has received packets into RX buffer successfully -- * -- * FTMAC100_INT_NORXBUF: -- * RX buffer unavailable -- */ -- bool retry; -- -- do { -- retry = ftmac100_rx_packet(priv, &rx); -- } while (retry && rx < budget); -+ struct net_device *ndev = platform_get_drvdata(pdev); - -- if (retry && rx == budget) -- completed = false; -- } -- -- if (status & (FTMAC100_INT_XPKT_OK | FTMAC100_INT_XPKT_LOST)) { -- /* -- * FTMAC100_INT_XPKT_OK: -- * packet transmitted to ethernet successfully -- * -- * FTMAC100_INT_XPKT_LOST: -- * packet transmitted to ethernet lost due to late -- * collision or excessive collision -- */ -- ftmac100_tx_complete(priv); -- } -- -- if (status & (FTMAC100_INT_NORXBUF | FTMAC100_INT_RPKT_LOST | -- FTMAC100_INT_AHB_ERR | FTMAC100_INT_PHYSTS_CHG)) { -- if (net_ratelimit()) -- netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status, -- status & FTMAC100_INT_NORXBUF ? "NORXBUF " : "", -- status & FTMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "", -- status & FTMAC100_INT_AHB_ERR ? "AHB_ERR " : "", -- status & FTMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : ""); -- -- if (status & FTMAC100_INT_NORXBUF) { -- /* RX buffer unavailable */ -- netdev->stats.rx_over_errors++; -- } -- -- if (status & FTMAC100_INT_RPKT_LOST) { -- /* received packet lost due to RX FIFO full */ -- netdev->stats.rx_fifo_errors++; -- } -- -- if (status & FTMAC100_INT_PHYSTS_CHG) { -- /* PHY link status change */ -- mii_check_link(&priv->mii); -+ if (ndev) { -+ if (netif_running(ndev)) { -+ netif_device_detach(ndev); -+ ftmac100_shutdown(ndev->base_addr); - } - } -- -- if (completed) { -- /* stop polling */ -- napi_complete(napi); -- ftmac100_enable_all_int(priv); -- } -- -- return rx; --} -- --/****************************************************************************** -- * struct net_device_ops functions -- *****************************************************************************/ --static int ftmac100_open(struct net_device *netdev) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- int err; -- -- err = ftmac100_alloc_buffers(priv); -- if (err) { -- netdev_err(netdev, "failed to allocate buffers\n"); -- goto err_alloc; -- } -- -- err = request_irq(priv->irq, ftmac100_interrupt, 0, netdev->name, netdev); -- if (err) { -- netdev_err(netdev, "failed to request irq %d\n", priv->irq); -- goto err_irq; -- } -- -- priv->rx_pointer = 0; -- priv->tx_clean_pointer = 0; -- priv->tx_pointer = 0; -- priv->tx_pending = 0; -- -- err = ftmac100_start_hw(priv); -- if (err) -- goto err_hw; -- -- napi_enable(&priv->napi); -- netif_start_queue(netdev); -- -- ftmac100_enable_all_int(priv); -- -- return 0; -- --err_hw: -- free_irq(priv->irq, netdev); --err_irq: -- ftmac100_free_buffers(priv); --err_alloc: -- return err; --} -- --static int ftmac100_stop(struct net_device *netdev) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- -- ftmac100_disable_all_int(priv); -- netif_stop_queue(netdev); -- napi_disable(&priv->napi); -- ftmac100_stop_hw(priv); -- free_irq(priv->irq, netdev); -- ftmac100_free_buffers(priv); -- - return 0; - } - --static int ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev) -+static int ftmac100_resume(struct platform_device *pdev) - { -- struct ftmac100 *priv = netdev_priv(netdev); -- dma_addr_t map; -- -- if (unlikely(skb->len > MAX_PKT_SIZE)) { -- if (net_ratelimit()) -- netdev_dbg(netdev, "tx packet too big\n"); -- -- netdev->stats.tx_dropped++; -- dev_kfree_skb(skb); -- return NETDEV_TX_OK; -- } -+ struct net_device *ndev = platform_get_drvdata(pdev); - -- map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE); -- if (unlikely(dma_mapping_error(priv->dev, map))) { -- /* drop packet */ -- if (net_ratelimit()) -- netdev_err(netdev, "map socket buffer failed\n"); -- -- netdev->stats.tx_dropped++; -- dev_kfree_skb(skb); -- return NETDEV_TX_OK; -+ if (ndev) { -+ if (netif_running(ndev)) { -+ ftmac100_reset(ndev); -+ ftmac100_enable(ndev); -+ netif_device_attach(ndev); -+ } - } -- -- return ftmac100_xmit(priv, skb, map); -+ return 0; - } - --/* optional */ --static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) --{ -- struct ftmac100 *priv = netdev_priv(netdev); -- struct mii_ioctl_data *data = if_mii(ifr); -- -- return generic_mii_ioctl(&priv->mii, data, cmd, NULL); -+static void platform_device_release(struct device *dev){ - } - --static const struct net_device_ops ftmac100_netdev_ops = { -- .ndo_open = ftmac100_open, -- .ndo_stop = ftmac100_stop, -- .ndo_start_xmit = ftmac100_hard_start_xmit, -- .ndo_set_mac_address = eth_mac_addr, -- .ndo_validate_addr = eth_validate_addr, -- .ndo_do_ioctl = ftmac100_do_ioctl, -+static struct platform_driver ftmac100_driver = { -+ .probe = ftmac100_probe, -+ .remove = ftmac100_remove, -+ .suspend = ftmac100_suspend, -+ .resume = ftmac100_resume, -+ .driver = { -+ .name = "ftmac100", -+ }, - }; - --/****************************************************************************** -- * struct platform_driver functions -- *****************************************************************************/ --static int ftmac100_probe(struct platform_device *pdev) --{ -- struct resource *res; -- int irq; -- struct net_device *netdev; -- struct ftmac100 *priv; -- int err; -- -- if (!pdev) -- return -ENODEV; -- -- res = platform_get_resource(pdev, IORESOURCE_MEM, 0); -- if (!res) -- return -ENXIO; -- -- irq = platform_get_irq(pdev, 0); -- if (irq < 0) -- return irq; -- -- /* setup net_device */ -- netdev = alloc_etherdev(sizeof(*priv)); -- if (!netdev) { -- err = -ENOMEM; -- goto err_alloc_etherdev; -- } -- -- SET_NETDEV_DEV(netdev, &pdev->dev); -- SET_ETHTOOL_OPS(netdev, &ftmac100_ethtool_ops); -- netdev->netdev_ops = &ftmac100_netdev_ops; -- -- platform_set_drvdata(pdev, netdev); -- -- /* setup private data */ -- priv = netdev_priv(netdev); -- priv->netdev = netdev; -- priv->dev = &pdev->dev; -- -- spin_lock_init(&priv->tx_lock); -- -- /* initialize NAPI */ -- netif_napi_add(netdev, &priv->napi, ftmac100_poll, 64); -- -- /* map io memory */ -- priv->res = request_mem_region(res->start, resource_size(res), -- dev_name(&pdev->dev)); -- if (!priv->res) { -- dev_err(&pdev->dev, "Could not reserve memory region\n"); -- err = -ENOMEM; -- goto err_req_mem; -- } -- -- priv->base = ioremap(res->start, resource_size(res)); -- if (!priv->base) { -- dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); -- err = -EIO; -- goto err_ioremap; -- } -- -- priv->irq = irq; -- -- /* initialize struct mii_if_info */ -- priv->mii.phy_id = 0; -- priv->mii.phy_id_mask = 0x1f; -- priv->mii.reg_num_mask = 0x1f; -- priv->mii.dev = netdev; -- priv->mii.mdio_read = ftmac100_mdio_read; -- priv->mii.mdio_write = ftmac100_mdio_write; -- -- /* register network device */ -- err = register_netdev(netdev); -- if (err) { -- dev_err(&pdev->dev, "Failed to register netdev\n"); -- goto err_register_netdev; -- } -- -- netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base); -- -- if (!is_valid_ether_addr(netdev->dev_addr)) { -- eth_hw_addr_random(netdev); -- netdev_info(netdev, "generated random MAC address %pM\n", -- netdev->dev_addr); -- } -- -- return 0; -- --err_register_netdev: -- iounmap(priv->base); --err_ioremap: -- release_resource(priv->res); --err_req_mem: -- netif_napi_del(&priv->napi); -- platform_set_drvdata(pdev, NULL); -- free_netdev(netdev); --err_alloc_etherdev: -- return err; --} -- --static int __exit ftmac100_remove(struct platform_device *pdev) --{ -- struct net_device *netdev; -- struct ftmac100 *priv; -- -- netdev = platform_get_drvdata(pdev); -- priv = netdev_priv(netdev); -- -- unregister_netdev(netdev); -- -- iounmap(priv->base); -- release_resource(priv->res); -- -- netif_napi_del(&priv->napi); -- platform_set_drvdata(pdev, NULL); -- free_netdev(netdev); -- return 0; --} -+static struct resource ftmac100_resources_a320[] = { -+ [0] = { -+ .start = MAC_FTMAC100_0_VA_BASE, -+ .end = MAC_FTMAC100_0_VA_LIMIT, -+ .flags = IORESOURCE_IO, -+ }, -+ [1] = { -+ .start = MAC_FTMAC100_0_IRQ, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; - --static struct platform_driver ftmac100_driver = { -- .probe = ftmac100_probe, -- .remove = __exit_p(ftmac100_remove), -- .driver = { -- .name = DRV_NAME, -- .owner = THIS_MODULE, -+static struct platform_device ftmac100_device_a320 = { -+ .name = "ftmac100", -+ .id = 0, -+ .num_resources = ARRAY_SIZE(ftmac100_resources_a320), -+ .resource = ftmac100_resources_a320, -+ .dev = { -+ .release = platform_device_release, - }, - }; - --/****************************************************************************** -- * initialization / finalization -- *****************************************************************************/ -+ - static int __init ftmac100_init(void) - { -- pr_info("Loading version " DRV_VERSION " ...\n"); -+ platform_device_register(&ftmac100_device_a320); - return platform_driver_register(&ftmac100_driver); - } - - static void __exit ftmac100_exit(void) - { - platform_driver_unregister(&ftmac100_driver); -+ platform_device_unregister(&ftmac100_device_a320); - } - - module_init(ftmac100_init); - module_exit(ftmac100_exit); -- --MODULE_AUTHOR("Po-Yu Chuang "); --MODULE_DESCRIPTION("FTMAC100 driver"); --MODULE_LICENSE("GPL"); -diff -Nur linux-3.4.113.orig/drivers/net/ethernet/faraday/ftmac100.h linux-3.4.113/drivers/net/ethernet/faraday/ftmac100.h ---- linux-3.4.113.orig/drivers/net/ethernet/faraday/ftmac100.h 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/net/ethernet/faraday/ftmac100.h 2016-12-01 20:59:24.388614139 +0100 -@@ -1,180 +1,267 @@ - /* -- * Faraday FTMAC100 10/100 Ethernet -+ * drivers/net/ftmac100.h - * -- * (C) Copyright 2009-2011 Faraday Technology -- * Po-Yu Chuang -+ * Faraday FTMAC100 Device Driver - * -- * 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. -+ * Copyright (C) 2005 Faraday Corp. (http://www.faraday-tech.com) -+ * -+ * All Rights Reserved - * -- * 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., 675 Mass Ave, Cambridge, MA 02139, USA. -- */ -- --#ifndef __FTMAC100_H --#define __FTMAC100_H -- --#define FTMAC100_OFFSET_ISR 0x00 --#define FTMAC100_OFFSET_IMR 0x04 --#define FTMAC100_OFFSET_MAC_MADR 0x08 --#define FTMAC100_OFFSET_MAC_LADR 0x0c --#define FTMAC100_OFFSET_MAHT0 0x10 --#define FTMAC100_OFFSET_MAHT1 0x14 --#define FTMAC100_OFFSET_TXPD 0x18 --#define FTMAC100_OFFSET_RXPD 0x1c --#define FTMAC100_OFFSET_TXR_BADR 0x20 --#define FTMAC100_OFFSET_RXR_BADR 0x24 --#define FTMAC100_OFFSET_ITC 0x28 --#define FTMAC100_OFFSET_APTC 0x2c --#define FTMAC100_OFFSET_DBLAC 0x30 --#define FTMAC100_OFFSET_MACCR 0x88 --#define FTMAC100_OFFSET_MACSR 0x8c --#define FTMAC100_OFFSET_PHYCR 0x90 --#define FTMAC100_OFFSET_PHYWDATA 0x94 --#define FTMAC100_OFFSET_FCR 0x98 --#define FTMAC100_OFFSET_BPR 0x9c --#define FTMAC100_OFFSET_TS 0xc4 --#define FTMAC100_OFFSET_DMAFIFOS 0xc8 --#define FTMAC100_OFFSET_TM 0xcc --#define FTMAC100_OFFSET_TX_MCOL_SCOL 0xd4 --#define FTMAC100_OFFSET_RPF_AEP 0xd8 --#define FTMAC100_OFFSET_XM_PG 0xdc --#define FTMAC100_OFFSET_RUNT_TLCC 0xe0 --#define FTMAC100_OFFSET_CRCER_FTL 0xe4 --#define FTMAC100_OFFSET_RLC_RCC 0xe8 --#define FTMAC100_OFFSET_BROC 0xec --#define FTMAC100_OFFSET_MULCA 0xf0 --#define FTMAC100_OFFSET_RP 0xf4 --#define FTMAC100_OFFSET_XP 0xf8 -- --/* -- * Interrupt status register & interrupt mask register -- */ --#define FTMAC100_INT_RPKT_FINISH (1 << 0) --#define FTMAC100_INT_NORXBUF (1 << 1) --#define FTMAC100_INT_XPKT_FINISH (1 << 2) --#define FTMAC100_INT_NOTXBUF (1 << 3) --#define FTMAC100_INT_XPKT_OK (1 << 4) --#define FTMAC100_INT_XPKT_LOST (1 << 5) --#define FTMAC100_INT_RPKT_SAV (1 << 6) --#define FTMAC100_INT_RPKT_LOST (1 << 7) --#define FTMAC100_INT_AHB_ERR (1 << 8) --#define FTMAC100_INT_PHYSTS_CHG (1 << 9) -- --/* -- * Interrupt timer control register - */ --#define FTMAC100_ITC_RXINT_CNT(x) (((x) & 0xf) << 0) --#define FTMAC100_ITC_RXINT_THR(x) (((x) & 0x7) << 4) --#define FTMAC100_ITC_RXINT_TIME_SEL (1 << 7) --#define FTMAC100_ITC_TXINT_CNT(x) (((x) & 0xf) << 8) --#define FTMAC100_ITC_TXINT_THR(x) (((x) & 0x7) << 12) --#define FTMAC100_ITC_TXINT_TIME_SEL (1 << 15) - --/* -- * Automatic polling timer control register -- */ --#define FTMAC100_APTC_RXPOLL_CNT(x) (((x) & 0xf) << 0) --#define FTMAC100_APTC_RXPOLL_TIME_SEL (1 << 4) --#define FTMAC100_APTC_TXPOLL_CNT(x) (((x) & 0xf) << 8) --#define FTMAC100_APTC_TXPOLL_TIME_SEL (1 << 12) -+#ifndef _FTMAC100_H_ -+#define _FTMAC100_H_ - --/* -- * DMA burst length and arbitration control register -- */ --#define FTMAC100_DBLAC_INCR4_EN (1 << 0) --#define FTMAC100_DBLAC_INCR8_EN (1 << 1) --#define FTMAC100_DBLAC_INCR16_EN (1 << 2) --#define FTMAC100_DBLAC_RXFIFO_LTHR(x) (((x) & 0x7) << 3) --#define FTMAC100_DBLAC_RXFIFO_HTHR(x) (((x) & 0x7) << 6) --#define FTMAC100_DBLAC_RX_THR_EN (1 << 9) -+#define ISR_REG 0x00 // interrups status register -+#define IMR_REG 0x04 // interrupt maks register -+#define MAC_MADR_REG 0x08 // MAC address (Most significant) -+#define MAC_LADR_REG 0x0c // MAC address (Least significant) -+ -+#define MAHT0_REG 0x10 // Multicast Address Hash Table 0 register -+#define MAHT1_REG 0x14 // Multicast Address Hash Table 1 register -+#define TXPD_REG 0x18 // Transmit Poll Demand register -+#define RXPD_REG 0x1c // Receive Poll Demand register -+#define TXR_BADR_REG 0x20 // Transmit Ring Base Address register -+#define RXR_BADR_REG 0x24 // Receive Ring Base Address register -+#define ITC_REG 0x28 // interrupt timer control register -+#define APTC_REG 0x2c // Automatic Polling Timer control register -+#define DBLAC_REG 0x30 // DMA Burst Length and Arbitration control register -+ -+ -+ -+#define MACCR_REG 0x88 // MAC control register -+#define MACSR_REG 0x8c // MAC status register -+#define PHYCR_REG 0x90 // PHY control register -+#define PHYWDATA_REG 0x94 // PHY Write Data register -+#define FCR_REG 0x98 // Flow Control register -+#define BPR_REG 0x9c // back pressure register -+#define WOLCR_REG 0xa0 // Wake-On-Lan control register -+#define WOLSR_REG 0xa4 // Wake-On-Lan status register -+#define WFCRC_REG 0xa8 // Wake-up Frame CRC register -+#define WFBM1_REG 0xb0 // wake-up frame byte mask 1st double word register -+#define WFBM2_REG 0xb4 // wake-up frame byte mask 2nd double word register -+#define WFBM3_REG 0xb8 // wake-up frame byte mask 3rd double word register -+#define WFBM4_REG 0xbc // wake-up frame byte mask 4th double word register -+#define TM_REG 0xcc // test mode register -+ -+#define PHYSTS_CHG_bit (1UL<<9) -+#define AHB_ERR_bit (1UL<<8) -+#define RPKT_LOST_bit (1UL<<7) -+#define RPKT_SAV_bit (1UL<<6) -+#define XPKT_LOST_bit (1UL<<5) -+#define XPKT_OK_bit (1UL<<4) -+#define NOTXBUF_bit (1UL<<3) -+#define XPKT_FINISH_bit (1UL<<2) -+#define NORXBUF_bit (1UL<<1) -+#define RPKT_FINISH_bit (1UL<<0) -+ -+ -+#ifdef __NDS32_EB__ -+typedef struct -+{ -+ unsigned int Reserved2:19; -+ unsigned int TXPOLL_TIME_SEL:1; -+ unsigned int TXPOLL_CNT:4; -+ unsigned int Reserved1:3; -+ unsigned int RXPOLL_TIME_SEL:1; -+ unsigned int RXPOLL_CNT:4; -+}FTMAC100_APTCR_Status; -+#else -+typedef struct -+{ -+ unsigned int RXPOLL_CNT:4; -+ unsigned int RXPOLL_TIME_SEL:1; -+ unsigned int Reserved1:3; -+ unsigned int TXPOLL_CNT:4; -+ unsigned int TXPOLL_TIME_SEL:1; -+ unsigned int Reserved2:19; -+} FTMAC100_APTCR_Status; -+#endif -+ -+#define RX_BROADPKT_bit (1UL<<17) // Receiving broadcast packet -+#define RX_MULTIPKT_bit (1UL<<16) // receiving multicast packet -+#define FULLDUP_bit (1UL<<15) // full duplex -+#define CRC_APD_bit (1UL<<14) // append crc to transmit packet -+#define MDC_SEL_bit (1UL<<13) // set MDC as TX_CK/10 -+#define RCV_ALL_bit (1UL<<12) // not check incoming packet's destination address -+#define RX_FTL_bit (1UL<<11) // Store incoming packet even its length is great than 1518 byte -+#define RX_RUNT_bit (1UL<<10) // Store incoming packet even its length is les than 64 byte -+#define HT_MULTI_EN_bit (1UL<<9) -+#define RCV_EN_bit (1UL<<8) // receiver enable -+#define XMT_EN_bit (1UL<<5) // transmitter enable -+#define CRC_DIS_bit (1UL<<4) -+#define LOOP_EN_bit (1UL<<3) // Internal loop-back -+#define SW_RST_bit (1UL<<2) // software reset/ -+#define RDMA_EN_bit (1UL<<1) // enable DMA receiving channel -+#define XDMA_EN_bit (1UL<<0) // enable DMA transmitting channel -+ -+ -+// -------------------------------------------------------------------- -+// Receive Ring descriptor structure -+// -------------------------------------------------------------------- -+#ifdef __NDS32_EB__ -+typedef struct -+{ -+ // RXDES0 -+ unsigned int RXDMA_OWN:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software -+ unsigned int Reserved3:1; -+ unsigned int FRS:1; -+ unsigned int LRS:1; -+ unsigned int Reserved2:5; -+ unsigned int RX_ODD_NB:1; -+ unsigned int RUNT:1; -+ unsigned int FTL:1; -+ unsigned int CRC_ERR:1; //19 -+ unsigned int RX_ERR:1; //18 -+ unsigned int BROARDCAST:1; //17 -+ unsigned int MULTICAST:1; //16 -+ unsigned int Reserved1:5; //11~15 -+ unsigned int ReceiveFrameLength:11;//0~10 -+ -+ // RXDES1 -+ unsigned int EDOTR:1; -+ unsigned int Reserved:20; -+ unsigned int RXBUF_Size:11; -+ -+ // RXDES2 -+ unsigned int RXBUF_BADR; -+ -+ unsigned int VIR_RXBUF_BADR; // not defined, §Ú­Ì®³¨Ó©ñ receive buffer ªº virtual address -+ -+}RX_DESC; -+ -+ -+typedef struct -+{ -+ // TXDES0 -+ unsigned int TXDMA_OWN:1; -+ unsigned int Reserved1:29; -+ unsigned int TXPKT_EXSCOL:1; -+ unsigned int TXPKT_LATECOL:1; -+ -+ // TXDES1 -+ unsigned int EDOTR:1; -+ unsigned int TXIC:1; -+ unsigned int TX2FIC:1; -+ unsigned int FTS:1; -+ unsigned int LTS:1; -+ unsigned int Reserved2:16; -+ unsigned int TXBUF_Size:11; -+ -+ // RXDES2 -+ unsigned int TXBUF_BADR; -+ unsigned int VIR_TXBUF_BADR; -+}TX_DESC; -+#else -+typedef struct -+{ -+ // RXDES0 -+ unsigned int ReceiveFrameLength:11;//0~10 -+ unsigned int Reserved1:5; //11~15 -+ unsigned int MULTICAST:1; //16 -+ unsigned int BROARDCAST:1; //17 -+ unsigned int RX_ERR:1; //18 -+ unsigned int CRC_ERR:1; //19 -+ unsigned int FTL:1; -+ unsigned int RUNT:1; -+ unsigned int RX_ODD_NB:1; -+ unsigned int Reserved2:5; -+ unsigned int LRS:1; -+ unsigned int FRS:1; -+ unsigned int Reserved3:1; -+ unsigned int RXDMA_OWN:1; // 1 ==> owned by FTMAC100, 0 ==> owned by software -+ -+ // RXDES1 -+ unsigned int RXBUF_Size:11; -+ unsigned int Reserved:20; -+ unsigned int EDOTR:1; -+ -+ // RXDES2 -+ unsigned int RXBUF_BADR; -+ -+ unsigned int VIR_RXBUF_BADR; // not defined, §Ú­Ì®³¨Ó©ñ receive buffer ªº virtual address -+ -+} RX_DESC; -+ -+ -+typedef struct -+{ -+ // TXDES0 -+ unsigned int TXPKT_LATECOL:1; -+ unsigned int TXPKT_EXSCOL:1; -+ unsigned int Reserved1:29; -+ unsigned int TXDMA_OWN:1; -+ -+ // TXDES1 -+ unsigned int TXBUF_Size:11; -+ unsigned int Reserved2:16; -+ unsigned int LTS:1; -+ unsigned int FTS:1; -+ unsigned int TX2FIC:1; -+ unsigned int TXIC:1; -+ unsigned int EDOTR:1; -+ -+ // RXDES2 -+ unsigned int TXBUF_BADR; -+ unsigned int VIR_TXBUF_BADR; -+} TX_DESC; -+#endif -+ -+// waiting to do: -+#define TXPOLL_CNT 8 -+#define RXPOLL_CNT 0 -+ -+#define OWNBY_SOFTWARE 0 -+#define OWNBY_FTMAC100 1 -+ -+// -------------------------------------------------------------------- -+// driver related definition -+// -------------------------------------------------------------------- -+#define RXDES_NUM 256 // must be 2's power -+#define RX_BUF_SIZE 1536 -+#define TXDES_NUM 64 // must be 2's power -+#define TX_BUF_SIZE 1536 // Luke Lee : Just bigger than 1518 -+ -+ -+struct ftmac100_local -+{ -+ // these are things that the kernel wants me to keep, so users -+ // can find out semi-useless statistics of how well the card is -+ // performing -+ struct net_device_stats stats; -+ -+ // Set to true during the auto-negotiation sequence -+ int autoneg_active; -+ -+ // Address of our PHY port -+ unsigned int phyaddr; -+ -+ // Type of PHY -+ unsigned int phytype; -+ -+ // Last contents of PHY Register 18 -+ unsigned int lastPhy18; -+ -+ spinlock_t lock; -+ -+ volatile RX_DESC *rx_descs; // receive ring base address -+ unsigned int rx_descs_dma; // receive ring physical base address -+ char *rx_buf; // receive buffer cpu address -+ int rx_buf_dma; // receive buffer physical address -+ int rx_idx; // receive descriptor -+ //struct sk_buff *rx_skbuff[RXDES_NUM]; -+ -+ volatile TX_DESC *tx_descs; -+ unsigned int tx_descs_dma; -+ char *tx_buf; -+ int tx_buf_dma; -+ int tx_idx; -+ int old_tx; -+ struct sk_buff *tx_skbuff[RXDES_NUM]; -+ -+ int maccr_val; -+}; - --/* -- * MAC control register -- */ --#define FTMAC100_MACCR_XDMA_EN (1 << 0) --#define FTMAC100_MACCR_RDMA_EN (1 << 1) --#define FTMAC100_MACCR_SW_RST (1 << 2) --#define FTMAC100_MACCR_LOOP_EN (1 << 3) --#define FTMAC100_MACCR_CRC_DIS (1 << 4) --#define FTMAC100_MACCR_XMT_EN (1 << 5) --#define FTMAC100_MACCR_ENRX_IN_HALFTX (1 << 6) --#define FTMAC100_MACCR_RCV_EN (1 << 8) --#define FTMAC100_MACCR_HT_MULTI_EN (1 << 9) --#define FTMAC100_MACCR_RX_RUNT (1 << 10) --#define FTMAC100_MACCR_RX_FTL (1 << 11) --#define FTMAC100_MACCR_RCV_ALL (1 << 12) --#define FTMAC100_MACCR_CRC_APD (1 << 14) --#define FTMAC100_MACCR_FULLDUP (1 << 15) --#define FTMAC100_MACCR_RX_MULTIPKT (1 << 16) --#define FTMAC100_MACCR_RX_BROADPKT (1 << 17) -- --/* -- * PHY control register -- */ --#define FTMAC100_PHYCR_MIIRDATA 0xffff --#define FTMAC100_PHYCR_PHYAD(x) (((x) & 0x1f) << 16) --#define FTMAC100_PHYCR_REGAD(x) (((x) & 0x1f) << 21) --#define FTMAC100_PHYCR_MIIRD (1 << 26) --#define FTMAC100_PHYCR_MIIWR (1 << 27) -- --/* -- * PHY write data register -- */ --#define FTMAC100_PHYWDATA_MIIWDATA(x) ((x) & 0xffff) -- --/* -- * Transmit descriptor, aligned to 16 bytes -- */ --struct ftmac100_txdes { -- unsigned int txdes0; -- unsigned int txdes1; -- unsigned int txdes2; /* TXBUF_BADR */ -- unsigned int txdes3; /* not used by HW */ --} __attribute__ ((aligned(16))); -- --#define FTMAC100_TXDES0_TXPKT_LATECOL (1 << 0) --#define FTMAC100_TXDES0_TXPKT_EXSCOL (1 << 1) --#define FTMAC100_TXDES0_TXDMA_OWN (1 << 31) -- --#define FTMAC100_TXDES1_TXBUF_SIZE(x) ((x) & 0x7ff) --#define FTMAC100_TXDES1_LTS (1 << 27) --#define FTMAC100_TXDES1_FTS (1 << 28) --#define FTMAC100_TXDES1_TX2FIC (1 << 29) --#define FTMAC100_TXDES1_TXIC (1 << 30) --#define FTMAC100_TXDES1_EDOTR (1 << 31) -- --/* -- * Receive descriptor, aligned to 16 bytes -- */ --struct ftmac100_rxdes { -- unsigned int rxdes0; -- unsigned int rxdes1; -- unsigned int rxdes2; /* RXBUF_BADR */ -- unsigned int rxdes3; /* not used by HW */ --} __attribute__ ((aligned(16))); -- --#define FTMAC100_RXDES0_RFL 0x7ff --#define FTMAC100_RXDES0_MULTICAST (1 << 16) --#define FTMAC100_RXDES0_BROADCAST (1 << 17) --#define FTMAC100_RXDES0_RX_ERR (1 << 18) --#define FTMAC100_RXDES0_CRC_ERR (1 << 19) --#define FTMAC100_RXDES0_FTL (1 << 20) --#define FTMAC100_RXDES0_RUNT (1 << 21) --#define FTMAC100_RXDES0_RX_ODD_NB (1 << 22) --#define FTMAC100_RXDES0_LRS (1 << 28) --#define FTMAC100_RXDES0_FRS (1 << 29) --#define FTMAC100_RXDES0_RXDMA_OWN (1 << 31) -+#endif - --#define FTMAC100_RXDES1_RXBUF_SIZE(x) ((x) & 0x7ff) --#define FTMAC100_RXDES1_EDORR (1 << 31) - --#endif /* __FTMAC100_H */ -diff -Nur linux-3.4.113.orig/drivers/net/ethernet/faraday/Kconfig linux-3.4.113/drivers/net/ethernet/faraday/Kconfig ---- linux-3.4.113.orig/drivers/net/ethernet/faraday/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/net/ethernet/faraday/Kconfig 2016-12-01 20:59:24.388614139 +0100 -@@ -5,7 +5,7 @@ - config NET_VENDOR_FARADAY - bool "Faraday devices" - default y -- depends on ARM -+ depends on ARM || NDS32 - ---help--- - If you have a network (Ethernet) card belonging to this class, say Y - and read the Ethernet-HOWTO, available from -@@ -20,7 +20,7 @@ - - config FTMAC100 - tristate "Faraday FTMAC100 10/100 Ethernet support" -- depends on ARM -+ depends on ARM || NDS32 - select NET_CORE - select MII - ---help--- -diff -Nur linux-3.4.113.orig/drivers/pci/Makefile linux-3.4.113/drivers/pci/Makefile ---- linux-3.4.113.orig/drivers/pci/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/pci/Makefile 2016-12-01 20:59:24.388614139 +0100 -@@ -49,6 +49,7 @@ - obj-$(CONFIG_MICROBLAZE) += setup-bus.o - obj-$(CONFIG_TILE) += setup-bus.o setup-irq.o - obj-$(CONFIG_SPARC_LEON) += setup-bus.o setup-irq.o -+obj-$(CONFIG_NDS32) += setup-bus.o setup-irq.o - - # - # ACPI Related PCI FW Functions -diff -Nur linux-3.4.113.orig/drivers/rtc/Kconfig linux-3.4.113/drivers/rtc/Kconfig ---- linux-3.4.113.orig/drivers/rtc/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/rtc/Kconfig 2016-12-01 20:59:24.388614139 +0100 -@@ -779,6 +779,16 @@ - This driver can also be built as a module. If so, the module - will be called rtc-ep93xx. - -+config RTC_DRV_FTRTC010 -+ tristate "Faraday Real Time Clock" -+ depends on NDS32 -+ help -+ If you say Y here you will get access to the real time clock -+ built into your AG101 CPU. -+ -+ To compile this driver as a module, choose M here: the -+ module will be called rtc-ftrtc010. -+ - config RTC_DRV_SA1100 - tristate "SA11x0/PXA2xx/PXA910" - depends on ARCH_SA1100 || ARCH_PXA || ARCH_MMP -diff -Nur linux-3.4.113.orig/drivers/rtc/Makefile linux-3.4.113/drivers/rtc/Makefile ---- linux-3.4.113.orig/drivers/rtc/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/rtc/Makefile 2016-12-01 20:59:24.388614139 +0100 -@@ -50,6 +50,7 @@ - obj-$(CONFIG_RTC_DRV_FM3130) += rtc-fm3130.o - obj-$(CONFIG_RTC_DRV_GENERIC) += rtc-generic.o - obj-$(CONFIG_RTC_DRV_IMXDI) += rtc-imxdi.o -+obj-$(CONFIG_RTC_DRV_FTRTC010) += rtc-ftrtc010.o - obj-$(CONFIG_RTC_DRV_ISL1208) += rtc-isl1208.o - obj-$(CONFIG_RTC_DRV_ISL12022) += rtc-isl12022.o - obj-$(CONFIG_RTC_DRV_JZ4740) += rtc-jz4740.o -diff -Nur linux-3.4.113.orig/drivers/rtc/rtc-ftrtc010.c linux-3.4.113/drivers/rtc/rtc-ftrtc010.c ---- linux-3.4.113.orig/drivers/rtc/rtc-ftrtc010.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/rtc/rtc-ftrtc010.c 2016-12-01 20:59:24.388614139 +0100 -@@ -0,0 +1,371 @@ -+/* -+ * Faraday RTC Support -+ * -+ * Copyright (C) 2006, 2007, 2008 Paul Mundt -+ * Copyright (C) 2006 Jamie Lenehan -+ * Copyright (C) 2008 Angelo Castello -+ * Copyright (C) 2008 Roy Lee -+ * -+ * Based on the old arch/sh/kernel/cpu/rtc.c by: -+ * -+ * Copyright (C) 2000 Philipp Rumpf -+ * Copyright (C) 1999 Tetsuya Okada & Niibe Yutaka -+ * -+ * This file is subject to the terms and conditions of the GNU General Public -+ * License. See the file "COPYING" in the main directory of this archive -+ * for more details. -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define PCLK ( AHB_CLK_IN / 2) -+ -+#define DRV_NAME "faraday-rtc" -+ -+#define RTC_REG( off) ( *( volatile unsigned long *)( rtc->regbase + ( off))) -+ -+#define RTC_CR RTC_REG( 0x20) /* Control */ -+#define RTC_CR_IE ( 0x1UL << 0) -+#define RTC_CR_IES ( 0x1UL << 1) -+#define RTC_CR_IEM ( 0x1UL << 2) -+#define RTC_CR_IEH ( 0x1UL << 3) -+#define RTC_CR_IED ( 0x1UL << 4) -+#define RTC_CR_ALRM ( 0x1UL << 5) -+#define RTC_CR_LOAD ( 0x1UL << 6) -+ -+#define RTC_RR RTC_REG( 0x1C) /* RTC Record Register */ -+#define RTC_DIV RTC_REG( 0x38) /* RTC Divede Register */ -+#define RTC_REV RTC_REG( 0x3C) /* RTC Divede Register */ -+ -+#define RTC_IR RTC_REG( 0x34) /* RTC interrupt state */ -+#define RTC_IR_IES ( 0x1UL << 0) /* RTC interrupt state */ -+#define RTC_IR_IEM ( 0x1UL << 1) /* RTC interrupt state */ -+#define RTC_IR_IEH ( 0x1UL << 2) /* RTC interrupt state */ -+#define RTC_IR_IED ( 0x1UL << 3) /* RTC interrupt state */ -+#define RTC_IR_ALRM ( 0x1UL << 4) /* RTC interrupt state */ -+ -+#define RTC_SECOND RTC_REG( 0x00) /* RTC sec */ -+#define RTC_MINUTE RTC_REG( 0x04) /* RTC min */ -+#define RTC_HOUR RTC_REG( 0x08) /* RTC hour */ -+#define RTC_DAYS RTC_REG( 0x0C) /* RTC day */ -+ -+#define RTC_ALRM_SECOND RTC_REG( 0x10) /* RTC alarm sec */ -+#define RTC_ALRM_MINUTE RTC_REG( 0x14) /* RTC alarm min */ -+#define RTC_ALRM_HOUR RTC_REG( 0x18) /* RTC alarm hour */ -+ -+#define RTC_WRITE_SECOND RTC_REG( 0x24) /* RTC write port for sec */ -+#define RTC_WRITE_MINUTE RTC_REG( 0x28) /* RTC write port for min */ -+#define RTC_WRITE_HOUR RTC_REG( 0x2C) /* RTC write port for hour */ -+#define RTC_WRITE_DAYS RTC_REG( 0x30) /* RTC write port for day */ -+ -+struct ft_rtc{ -+ -+ void __iomem *regbase; -+ struct resource *res; -+ unsigned int alarm_irq; -+ unsigned int interrupt_irq; -+ struct rtc_device *rtc_dev; -+ spinlock_t lock; /* Protects this structure */ -+}; -+ -+struct ft_rtc rtc_platform_data; -+ -+static irqreturn_t ft_rtc_interrupt( int irq, void *dev_id){ -+ -+ struct ft_rtc *rtc = dev_id; -+ if( RTC_IR & RTC_IR_IES){ -+ -+ RTC_IR &= ~RTC_IR_IES; -+ rtc_update_irq( rtc->rtc_dev, 1, RTC_UF | RTC_IRQF); -+ -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static irqreturn_t ft_rtc_alarm( int irq, void *dev_id){ -+ -+ struct ft_rtc *rtc = dev_id; -+ if( RTC_IR & RTC_IR_ALRM){ -+ -+ RTC_CR &= ~RTC_CR_ALRM; -+ RTC_IR &= ~RTC_IR_ALRM; -+ rtc_update_irq( rtc->rtc_dev, 1, RTC_AF | RTC_IRQF); -+ -+ return IRQ_HANDLED; -+ } -+ -+ return IRQ_NONE; -+} -+ -+static void ft_rtc_release( struct device *dev){ -+ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ -+ RTC_CR &= ~RTC_CR_IES; -+ RTC_CR &= ~RTC_CR_ALRM; -+} -+ -+/* rick add */ -+static int ft_alarm_irq_enable(struct device *dev, unsigned int enabled) -+{ -+// printk("\n\nft_alarm_irq_enable\n\n"); -+ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ spin_lock_irq(&rtc->lock); -+ if (enabled) -+ RTC_CR |= RTC_CR_ALRM; -+ else -+ RTC_CR &= ~RTC_CR_ALRM; -+ spin_unlock_irq(&rtc->lock); -+ return 0; -+} -+ -+static int ft_rtc_read_time( struct device *dev, struct rtc_time *tm){ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ unsigned long time = RTC_DAYS * 86400 + RTC_HOUR * 3600 + RTC_MINUTE * 60 + RTC_SECOND; -+ rtc_time_to_tm( time, tm); -+ if( rtc_valid_tm( tm) < 0) { -+ dev_err( dev, "invalid date\n"); -+ rtc_time_to_tm( 0, tm); -+ } -+ return 0; -+} -+ -+static int ft_rtc_set_time( struct device *dev, struct rtc_time *tm){ -+ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ unsigned long time = 0; -+ -+ rtc_tm_to_time( tm, &time); -+ -+ RTC_WRITE_DAYS = time / 86400; -+ time %= 86400; -+ -+ RTC_WRITE_HOUR = time / 3600; -+ time %= 3600; -+ -+ RTC_WRITE_MINUTE = time / 60; -+ time %= 60; -+ -+ RTC_WRITE_SECOND = time; -+ -+ RTC_CR |= RTC_CR_LOAD; -+ -+ return 0; -+} -+ -+static int ft_rtc_read_alarm( struct device *dev, struct rtc_wkalrm *wkalrm){ -+ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ struct rtc_time *tm = &wkalrm->time; -+ -+ tm->tm_sec = RTC_ALRM_SECOND; -+ tm->tm_min = RTC_ALRM_MINUTE; -+ tm->tm_hour = RTC_ALRM_HOUR; -+ -+ wkalrm->enabled = ( RTC_CR & RTC_CR_ALRM) ? 1 : 0; -+ -+ return 0; -+} -+ -+static int ft_rtc_set_alarm( struct device *dev, struct rtc_wkalrm *wkalrm){ -+ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ struct rtc_time *tm = &wkalrm->time; -+ int err = rtc_valid_tm( tm); -+ if( err < 0){ -+ -+ dev_err( dev, "invalid alarm value\n"); -+ return err; -+ } -+ -+ /* disable alarm interrupt and clear the alarm flag */ -+ RTC_CR &= ~RTC_CR_ALRM; -+ -+ /* set alarm time */ -+ RTC_ALRM_SECOND = tm->tm_sec; -+ RTC_ALRM_MINUTE = tm->tm_min; -+ RTC_ALRM_HOUR = tm->tm_hour; -+ -+ if( wkalrm->enabled) -+ RTC_CR |= RTC_CR_ALRM; -+ -+ return 0; -+} -+ -+/* -+static int ft_rtc_irq_set_state( struct device *dev, int enabled){ -+ struct ft_rtc *rtc = dev_get_drvdata( dev); -+ if( enabled) -+ RTC_CR |= RTC_CR_IES; -+ else -+ RTC_CR &= ~RTC_CR_IES; -+ -+ return 0; -+} -+ -+*/ -+ -+static struct rtc_class_ops ft_rtc_ops = { -+ -+ .release = ft_rtc_release, -+ .alarm_irq_enable = ft_alarm_irq_enable, -+ -+ .read_time = ft_rtc_read_time, -+ .set_time = ft_rtc_set_time, -+ .read_alarm = ft_rtc_read_alarm, -+ .set_alarm = ft_rtc_set_alarm, -+}; -+ -+static int __devinit ft_rtc_probe( struct platform_device *pdev){ -+ -+ struct ft_rtc *rtc = &rtc_platform_data; -+ int ret = -ENOENT; -+ spin_lock_init(&rtc->lock); -+ -+ if( ( rtc->alarm_irq = platform_get_irq( pdev, 0)) < 0) -+ goto err_exit; -+ -+ if( ( rtc->interrupt_irq = platform_get_irq( pdev, 1)) < 0) -+ goto err_exit; -+ -+ if( !( rtc->res = platform_get_resource( pdev, IORESOURCE_MEM, 0))) -+ goto err_exit; -+ -+ if( ( ret = request_irq( rtc->alarm_irq , ft_rtc_alarm, 0, "RTC Alarm : ftrtc010", rtc))) -+ goto err_exit; -+ -+ if( ( ret = request_irq( rtc->interrupt_irq , ft_rtc_interrupt, 0, "RTC Interrupt : ftrtc010", rtc))) -+ goto err_interrupt_irq; -+ -+ ret = -EBUSY; -+ -+ if( !( rtc->res = request_mem_region( rtc->res->start, rtc->res->end - rtc->res->start + 1, pdev->name))) -+ goto err_request_region; -+ -+ ret = -EINVAL; -+ -+ if( !( rtc->regbase = ioremap_nocache( rtc->res->start, rtc->res->end - rtc->res->start + 1))) -+ goto err_ioremap1; -+ -+ -+ //RTC_DIV = ( 0x1UL << 31) | 2; /* AG101 */ -+ RTC_CR |= RTC_CR_IE; -+ platform_set_drvdata( pdev, rtc); -+ device_init_wakeup(&pdev->dev, true); -+ -+ rtc->rtc_dev = rtc_device_register( DRV_NAME, &pdev->dev, &ft_rtc_ops, THIS_MODULE); -+ -+ if( IS_ERR( rtc->rtc_dev)) { -+ -+ ret = PTR_ERR( rtc->rtc_dev); -+ goto err_unmap; -+ } -+ -+ rtc->rtc_dev->max_user_freq = 256; -+ rtc->rtc_dev->irq_freq = 1; -+ return 0; -+ -+err_unmap: -+ iounmap( rtc->regbase); -+err_ioremap1: -+ release_resource( rtc->res); -+err_request_region: -+ free_irq( rtc->interrupt_irq, rtc); -+err_interrupt_irq: -+ free_irq( rtc->alarm_irq, rtc); -+err_exit: -+ return ret; -+} -+ -+static int __devexit ft_rtc_remove( struct platform_device *pdev){ -+ -+ struct ft_rtc *rtc = platform_get_drvdata( pdev); -+ -+ rtc_device_unregister( rtc->rtc_dev); -+ -+ RTC_CR &= ~RTC_CR_ALRM; -+ -+ free_irq( rtc->alarm_irq, rtc); -+ free_irq( rtc->interrupt_irq, rtc); -+ -+ iounmap( rtc->regbase); -+ -+ platform_set_drvdata( pdev, NULL); -+ -+ return 0; -+} -+ -+static void platform_device_release(struct device *dev){ -+} -+ -+static struct resource rtc_resources[] = { -+ { -+ .start = RTC_FTRTC010_PA_BASE, -+ .end = RTC_FTRTC010_PA_LIMIT, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = RTC_FTRTC010_IRQ0, -+ .end = RTC_FTRTC010_IRQ0, -+ .flags = IORESOURCE_IRQ, -+ }, -+ { -+ .start = RTC_FTRTC010_IRQ1, -+ .end = RTC_FTRTC010_IRQ1, -+ .flags = IORESOURCE_IRQ, -+ }, -+}; -+ -+static struct platform_driver ft_rtc_platform_driver = { -+ -+ .driver = { -+ .name = DRV_NAME, -+ .owner = THIS_MODULE, -+ }, -+ .probe = ft_rtc_probe, -+ .remove = __devexit_p( ft_rtc_remove), -+}; -+ -+static struct platform_device rtc_device = { -+ -+ .name = DRV_NAME, -+ .id = 0, -+ .resource = rtc_resources, -+ .num_resources = ARRAY_SIZE( rtc_resources), -+ .dev = { -+ .platform_data = &rtc_platform_data, -+ .release = platform_device_release, -+ }, -+}; -+ -+static int __init ft_rtc_init( void){ -+ platform_device_register( &rtc_device); -+ return platform_driver_register( &ft_rtc_platform_driver); -+} -+ -+static void __exit ft_rtc_exit( void){ -+ -+ platform_driver_unregister( &ft_rtc_platform_driver); -+ platform_device_unregister( &rtc_device); -+} -+ -+module_init( ft_rtc_init); -+module_exit( ft_rtc_exit); -+ -+MODULE_DESCRIPTION( "SuperH on-chip RTC driver"); -+MODULE_AUTHOR( "Paul Mundt , " -+ "Jamie Lenehan , " -+ "Angelo Castello , " -+ "Roy Lee "); -+MODULE_LICENSE( "GPL"); -+MODULE_ALIAS( "platform:" DRV_NAME); -diff -Nur linux-3.4.113.orig/drivers/tty/serial/8250/8250.c linux-3.4.113/drivers/tty/serial/8250/8250.c ---- linux-3.4.113.orig/drivers/tty/serial/8250/8250.c 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/tty/serial/8250/8250.c 2016-12-01 20:59:24.392614293 +0100 -@@ -570,6 +570,7 @@ - serial_out(up, UART_ICR, value); - } - -+#ifndef CONFIG_NDS32 - static unsigned int serial_icr_read(struct uart_8250_port *up, int offset) - { - unsigned int value; -@@ -581,6 +582,7 @@ - - return value; - } -+#endif - - /* - * FIFO support. -@@ -722,6 +724,7 @@ - return count; - } - -+#ifndef CONFIG_NDS32 - /* - * Read UART ID using the divisor method - set DLL and DLM to zero - * and the revision will be in DLL and device type in DLM. We -@@ -749,7 +752,9 @@ - - return id; - } -+#endif - -+#ifndef CONFIG_NDS32 - /* - * This is a helper routine to autodetect StarTech/Exar/Oxsemi UART's. - * When this function is called we know it is at least a StarTech -@@ -842,6 +847,7 @@ - else - up->port.type = PORT_16650V2; - } -+#endif - - /* - * We detected a chip without a FIFO. Only two fall into -@@ -865,6 +871,7 @@ - up->port.type = PORT_16450; - } - -+#ifndef CONFIG_NDS32 - static int broken_efr(struct uart_8250_port *up) - { - /* -@@ -877,6 +884,7 @@ - - return 0; - } -+#endif - - static inline int ns16550a_goto_highspeed(struct uart_8250_port *up) - { -@@ -908,7 +916,7 @@ - - up->port.type = PORT_16550A; - up->capabilities |= UART_CAP_FIFO; -- -+#ifndef CONFIG_NDS32 - /* - * Check for presence of the EFR when DLAB is set. - * Only ST16C650V1 UARTs pass this test. -@@ -937,6 +945,7 @@ - autoconfig_has_efr(up); - return; - } -+#endif - - /* - * Check for a National Semiconductor SuperIO chip. -@@ -1156,10 +1165,11 @@ - * We also initialise the EFR (if any) to zero for later. The - * EFR occupies the same register location as the FCR and IIR. - */ -+#ifndef CONFIG_NDS32 - serial_out(up, UART_LCR, UART_LCR_CONF_MODE_B); - serial_out(up, UART_EFR, 0); - serial_out(up, UART_LCR, 0); -- -+#endif - serial_out(up, UART_FCR, UART_FCR_ENABLE_FIFO); - scratch = serial_in(up, UART_IIR) >> 6; - -diff -Nur linux-3.4.113.orig/drivers/video/FTLCDC100/faradayfb.h linux-3.4.113/drivers/video/FTLCDC100/faradayfb.h ---- linux-3.4.113.orig/drivers/video/FTLCDC100/faradayfb.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/video/FTLCDC100/faradayfb.h 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1,215 @@ -+#ifndef __FARADAYFB_H -+#define __FARADAYFB_H -+ -+#define FARADAYFB_MODULE_NAME "faradayfb" -+#define DEBUG(enabled, tagged, ...) \ -+ do { \ -+ if (enabled) { \ -+ if (tagged) \ -+ printk("[ %30s() ] ", __func__); \ -+ printk(__VA_ARGS__); \ -+ } \ -+ } while (0) -+ -+#if defined(CONFIG_FFB_MODE_RGB) -+# define DEFAULT_COLOR FFB_MODE_RGB -+#elif defined(CONFIG_FFB_MODE_YUV422) -+# define DEFAULT_COLOR FFB_MODE_YUV422 -+#elif defined(CONFIG_FFB_MODE_YUV420) -+# define DEFAULT_COLOR FFB_MODE_YUV420 -+#endif -+ -+#if defined(CONFIG_FFB_MODE_8BPP) -+# define DEFAULT_BPP FFB_MODE_8BPP -+#elif defined(CONFIG_FFB_MODE_16BPP) -+# define DEFAULT_BPP FFB_MODE_16BPP -+#elif defined(CONFIG_FFB_MODE_24BPP) -+# define DEFAULT_BPP FFB_MODE_24BPP -+#endif -+ -+#define FFB_DEFAULT_MODE (DEFAULT_COLOR | DEFAULT_BPP) -+ -+struct lcd_param { -+ -+ unsigned long value; -+ unsigned long flags; -+}; -+ -+inline struct lcd_param* get_lcd_time(struct lcd_param* array, unsigned long num_array, unsigned long type) -+{ -+ int i; -+ -+ for (i = 0; i < num_array; i++) { -+ -+ struct lcd_param *r = &array[i]; -+ -+ if (r->flags & type & 0xff) -+ return r; -+ } -+ -+ return NULL; -+} -+ -+inline struct lcd_param* get_lcd_ctrl(struct lcd_param* array, unsigned long num_array, unsigned long type) -+{ -+ int i; -+ -+ for (i = 0; i < num_array; i++) { -+ -+ struct lcd_param *r = &array[i]; -+ -+ if ((r->flags & type & 0xff) && (r->flags & type & 0xff00)) -+ return r; -+ } -+ -+ return NULL; -+} -+ -+enum { RGB_8, RGB_16, RGB_24, NR_RGB}; -+ -+struct faradayfb_rgb { -+ -+ struct fb_bitfield red; -+ struct fb_bitfield green; -+ struct fb_bitfield blue; -+ struct fb_bitfield transp; -+}; -+ -+/* This structure describes the machine which we are running on. */ -+struct faradayfb_mach_info { -+ -+ unsigned long num_time0; -+ struct lcd_param * time0; -+ -+ unsigned long num_time1; -+ struct lcd_param * time1; -+ -+ unsigned long num_time2; -+ struct lcd_param * time2; -+ -+ unsigned long num_control; -+ struct lcd_param * control; -+ -+ unsigned long pixclock; -+ -+ unsigned long xres; -+ unsigned long yres; -+ -+ unsigned int max_bpp; -+ unsigned int sync; -+ -+ unsigned int cmap_greyscale:1, -+ cmap_inverse:1, -+ cmap_static:1, -+ unused:29; -+}; -+ -+struct faradayfb_info { -+ -+ struct fb_info *info; -+ struct faradayfb_rgb *rgb[NR_RGB]; -+ -+ unsigned int xres; -+ unsigned int yres; -+ unsigned int max_bpp; -+ -+ /* -+ * These are the addresses we mapped -+ * the framebuffer memory region to. -+ */ -+ dma_addr_t map_dma; -+ unsigned char * map_cpu; -+ unsigned int map_size; -+ -+ unsigned char * screen_cpu; -+ dma_addr_t screen_dma; -+ u32 * palette_cpu; -+ dma_addr_t palette_dma; -+ unsigned int palette_size; -+ -+ unsigned int cmap_inverse:1, -+ cmap_static:1, -+ unused:30; -+ -+ unsigned long time0; -+ unsigned long time1; -+ unsigned long time2; -+ unsigned long control; -+ unsigned long int_mask; -+ unsigned long io_base; -+ -+ unsigned int state; -+ unsigned int task_state; -+ struct semaphore ctrlr_sem; -+ wait_queue_head_t ctrlr_wait; -+ struct work_struct task; -+ -+ unsigned long smode; -+ unsigned long frame420_size; -+}; -+ -+/* -+ * These are the actions for set_ctrlr_state -+ */ -+#define C_DISABLE 0 -+#define C_ENABLE 1 -+#define C_DISABLE_CLKCHANGE 2 -+#define C_ENABLE_CLKCHANGE 3 -+#define C_REENABLE 4 -+#define C_DISABLE_PM 5 -+#define C_ENABLE_PM 6 -+#define C_STARTUP 7 -+ -+#define FARADAY_LCDTIME0_GET_HBP(x) ((((x) >> 24) & 0xFF) + 1) -+#define FARADAY_LCDTIME0_GET_HFP(x) ((((x) >> 16) & 0xFF) + 1) -+#define FARADAY_LCDTIME0_GET_HW(x) ((((x) >> 8) & 0xFF) + 1) -+#define FARADAY_LCDTIME1_GET_VBP(x) ((((x) >> 24) & 0xFF) ) -+#define FARADAY_LCDTIME1_GET_VFP(x) ((((x) >> 16) & 0xFF) ) -+#define FARADAY_LCDTIME1_GET_VW(x) ((((x) >> 8) & 0xFF) + 1) -+ -+#define FARADAY_LCDTIME0_HBP(x) ((((x) - 1) & 0xFF) << 24) -+#define FARADAY_LCDTIME0_HFP(x) ((((x) - 1) & 0xFF) << 16) -+#define FARADAY_LCDTIME0_HW(x) ((((x) - 1) & 0xFF) << 8) -+#define FARADAY_LCDTIME0_PL(x) (((((x) >> 4) - 1) & 0x3F) << 2) -+#define FARADAY_LCDTIME1_VBP(x) ((((x) ) & 0xFF) << 24) -+#define FARADAY_LCDTIME1_VFP(x) ((((x) ) & 0xFF) << 16) -+#define FARADAY_LCDTIME1_VW(x) ((((x) - 1) & 0xFF) << 8) -+#define FARADAY_LCDTIME1_LF(x) ((((x) - 1) & 0x3FF) ) -+ -+#define FFB_MODE_RGB 0x00000001 -+#define FFB_MODE_YUV420 0x00000002 -+#define FFB_MODE_YUV422 0x00000004 -+ -+#define FFB_MODE_8BPP 0x00000100 -+#define FFB_MODE_16BPP 0x00000200 -+#define FFB_MODE_24BPP 0x00000400 -+ -+/* Minimum X and Y resolutions */ -+#define MIN_XRES 64 -+#define MIN_YRES 64 -+ -+typedef struct LCDTag { -+ -+ u32 Timing0; /* 0x00 */ -+ u32 Timing1; /* 0x04 */ -+ u32 Timing2; /* 0x08 */ -+ u32 Timing3; /* 0x0C */ -+ u32 UPBase; /* 0x10 */ -+ u32 LPBase; /* 0x14 */ -+ u32 INTREnable; /* 0x18 */ -+ u32 Control; /* 0x1C */ -+ u32 Status; /* 0x20 */ -+ u32 Interrupt; /* 0x24 */ -+ u32 UPCurr; /* 0x28 */ -+ u32 LPCurr; /* 0x2C */ -+ u32 Reserved1[5]; /* 0x30~0x40 */ -+ u32 GPIO; /* 0x44 */ -+ u32 Reserved2[0x74 - 6]; /* 0x48~0x1FC */ -+ -+ u32 Palette[0x80]; /* 0x200~0x3FC */ -+ u32 TestReg[0x100]; /* 0x400~0x7FC */ -+ -+} LCD_Register; -+ -+#endif /* __FARADAYFB_H */ -+ -diff -Nur linux-3.4.113.orig/drivers/video/FTLCDC100/faradayfb-main.c linux-3.4.113/drivers/video/FTLCDC100/faradayfb-main.c ---- linux-3.4.113.orig/drivers/video/FTLCDC100/faradayfb-main.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/video/FTLCDC100/faradayfb-main.c 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1,911 @@ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+ -+#include "faradayfb.h" -+#include "lcd-info.c" -+#include "pingpong-module.c" -+ -+static u32 faradayfb_pseudo_palette[32]; -+static inline void faradayfb_lcd_power(struct fb_info *info, int on) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ -+ if (on) -+ fbi->control |= (1UL << 11); -+ else -+ fbi->control &= ~(1UL << 11); -+ -+ plcd->Control = fbi->control; -+} -+ -+static void faradayfb_setup_gpio(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ -+ plcd->GPIO = 0x010000; -+} -+ -+static inline void faradayfb_pmu_on(void) -+{ -+ REG32(PMU_FTPMU010_VA_BASE + 0x44) |= 0x00700000; -+} -+ -+static inline void faradayfb_pmu_off(void) -+{ -+ REG32(PMU_FTPMU010_VA_BASE + 0x44) &= ~0x00700000; -+} -+ -+static void faradayfb_enable_controller(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ -+ plcd->Timing0 = fbi->time0; -+ plcd->Timing1 = fbi->time1; -+ plcd->Timing2 = fbi->time2; -+ plcd->Control = fbi->control & ~0x01; -+ -+ plcd->UPBase = fbi->screen_dma | fbi->frame420_size; -+ -+ faradayfb_pmu_on(); -+ plcd->Control |= 0x01; -+ -+ DEBUG(0, 1, "Time0 = 0x%08x\n", plcd->Timing0); -+ DEBUG(0, 1, "Time1 = 0x%08x\n", plcd->Timing1); -+ DEBUG(0, 1, "Time2 = 0x%08x\n", plcd->Timing2); -+ DEBUG(0, 1, "Control = 0x%08x\n", plcd->Control); -+ DEBUG(0, 1, "UPBase = 0x%08x\n", plcd->UPBase); -+} -+ -+static void faradayfb_disable_controller(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ DECLARE_WAITQUEUE(wait, current); -+ -+ set_current_state(TASK_UNINTERRUPTIBLE); -+ add_wait_queue(&fbi->ctrlr_wait, &wait); -+ -+ fbi->control &= ~0x0001; -+ plcd->Control = fbi->control; -+ faradayfb_pmu_off(); -+ -+ schedule_timeout(20 * HZ / 1000); -+ remove_wait_queue(&fbi->ctrlr_wait, &wait); -+} -+ -+static void faradayfb_enable_int(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ -+ plcd->INTREnable = fbi->int_mask; -+} -+ -+static void faradayfb_disable_int(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ -+ fbi->int_mask = plcd->INTREnable; -+ plcd->INTREnable = 0; -+ plcd->Status = 0x1e; -+} -+ -+static struct faradayfb_rgb def_rgb_8 = { -+ -+ .red = { .offset = 0, .length = 4 }, -+ .green = { .offset = 0, .length = 4 }, -+ .blue = { .offset = 0, .length = 4 }, -+ .transp = { .offset = 0, .length = 0 }, -+}; -+ -+static struct faradayfb_rgb def_rgb_16 = { -+ -+ .red = { .offset = 11, .length = 5, .msb_right = 0 }, -+ .green = { .offset = 5, .length = 6, .msb_right = 0 }, -+ .blue = { .offset = 0, .length = 5, .msb_right = 0 }, -+ .transp = { .offset = 15, .length = 0, .msb_right = 0 }, -+}; -+ -+static struct faradayfb_rgb def_rgb_24 = { -+ -+ .red = { .offset = 16, .length = 8, .msb_right = 0 }, -+ .green = { .offset = 8, .length = 8, .msb_right = 0 }, -+ .blue = { .offset = 0, .length = 8, .msb_right = 0 }, -+ .transp = { .offset = 0, .length = 0, .msb_right = 0 }, -+}; -+ -+static inline void faradayfb_schedule_work(struct fb_info *info, unsigned int state) -+{ -+ struct faradayfb_info *fbi = info->par; -+ unsigned long flags; -+ -+ local_irq_save(flags); -+ -+ /* -+ * We need to handle two requests being made at the same time. -+ * There are two important cases: -+ * 1. When we are changing VT (C_REENABLE) while unblanking (C_ENABLE) -+ * We must perform the unblanking, which will do our REENABLE for us. -+ * 2. When we are blanking, but immediately unblank before we have -+ * blanked. We do the "REENABLE" thing here as well, just to be sure. -+ */ -+ if (fbi->task_state == C_ENABLE && state == C_REENABLE) -+ state = (unsigned int) - 1; -+ -+ if (fbi->task_state == C_DISABLE && state == C_ENABLE) -+ state = C_REENABLE; -+ -+ if (state != (unsigned int) - 1) { -+ -+ fbi->task_state = state; -+ schedule_work(&fbi->task); -+ } -+ -+ local_irq_restore(flags); -+} -+ -+static int faradayfb_setpalettereg(unsigned int regno, unsigned int red, -+ unsigned int green, unsigned int blue, unsigned int trans, -+ struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ -+ if (regno < fbi->palette_size) { -+ -+ fbi->palette_cpu[regno] = ((red >> 0) & (0x1fUL << 11)) | -+ ((green >> 5) & (0x3F << 5)) | -+ ((blue >> 11) & (0x1f << 0)); -+ -+ return 0; -+ } -+ -+ return 1; -+} -+ -+static int faradayfb_setcolreg(unsigned int regno, unsigned int red, unsigned int green, -+ unsigned int blue, unsigned int trans, struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ int ret = 1; -+ /* -+ * If inverse mode was selected, invert all the colours -+ * rather than the register number. The register number -+ * is what you poke into the framebuffer to produce the -+ * colour you requested. -+ */ -+ if (fbi->cmap_inverse) { -+ -+ red = 0xffff - red; -+ green = 0xffff - green; -+ blue = 0xffff - blue; -+ } -+ -+ /* -+ * If greyscale is true, then we convert the RGB value -+ * to greyscale no mater what visual we are using. -+ */ -+ if (info->var.grayscale) -+ red = green = blue = (19595 * red + 38470 * green + 7471 * blue) >> 16; -+ -+ switch(info->fix.visual) { -+ -+ case FB_VISUAL_TRUECOLOR: -+ /* -+ * 12 or 16-bit True Colour. We encode the RGB value -+ * according to the RGB bitfield information. -+ */ -+ if (regno < 16) { -+ -+ u32 col; -+ red >>= (16 - info->var.red.length); -+ green >>= (16 - info->var.green.length); -+ blue >>= (16 - info->var.blue.length); -+ col = (red << info->var.red.offset) | -+ (green << info->var.green.offset) | -+ (blue << info->var.blue.offset) ; -+ -+ switch(info->var.bits_per_pixel) { -+ -+ /* is the following code correct?? */ -+ case 16: -+ case 32: -+ ((u32 *)(info->pseudo_palette))[regno] = col; -+ ret=0; -+ break; -+ } -+ } -+ break; -+ -+ case FB_VISUAL_STATIC_PSEUDOCOLOR: -+ case FB_VISUAL_PSEUDOCOLOR: -+ if (fbi->smode == FFB_MODE_RGB) -+ ret = faradayfb_setpalettereg(regno, red, green, blue, trans, info); -+ break; -+ } -+ -+ return ret; -+} -+ -+/* -+ * Round up in the following order: bits_per_pixel, xres, -+ * yres, xres_virtual, yres_virtual, xoffset, yoffset, grayscale, -+ * bitfields, horizontal timing, vertical timing. -+ */ -+static int faradayfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ int rgbidx; -+ -+ var->xres = min(var->xres, (unsigned int)MIN_XRES); -+ var->yres = min(var->yres, (unsigned int)MIN_YRES); -+ var->xres = max(var->xres, fbi->xres); -+ var->yres = max(var->yres, fbi->yres); -+ var->xres_virtual = max(var->xres_virtual, var->xres); -+ var->yres_virtual = max(var->yres_virtual, var->yres); -+ -+ DEBUG(0, 1, "var->bits_per_pixel = %d\n", var->bits_per_pixel); -+ -+ switch (var->bits_per_pixel) { -+ -+ case 1: case 2: case 4: case 8: -+ rgbidx = RGB_8; -+ break; -+ -+ case 16: -+ rgbidx = RGB_16; -+ break; -+ -+ case 32: -+ rgbidx = RGB_24; -+ break; -+ -+ default: -+ return -EINVAL; -+ } -+ -+ /* -+ * Copy the RGB parameters for this display -+ * from the machine specific parameters. -+ */ -+ var->red = fbi->rgb[ rgbidx]->red; -+ var->green = fbi->rgb[ rgbidx]->green; -+ var->blue = fbi->rgb[ rgbidx]->blue; -+ var->transp = fbi->rgb[ rgbidx]->transp; -+ -+ DEBUG(0, 1, "RGBT length = %d:%d:%d:%d\n", -+ var->red.length, var->green.length, var->blue.length, var->transp.length); -+ -+ DEBUG(0, 1, "RGBT offset = %d:%d:%d:%d\n", -+ var->red.offset, var->green.offset, var->blue.offset, var->transp.offset); -+ -+ DEBUG(0, 1, "Leave\n"); -+ -+ return 0; -+} -+ -+/* -+ * Configures LCD Controller based on entries in var parameter. Settings are -+ * only written to the controller if changes were made. -+ */ -+static int faradayfb_activate_var(struct fb_var_screeninfo *var, struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ -+ DEBUG(0, 1, "var: xres=%d hslen=%d lm=%d rm=%d\n", var->xres, var->hsync_len, var->left_margin, var->right_margin); -+ DEBUG(0, 1, "var: yres=%d vslen=%d um=%d bm=%d\n", var->yres, var->vsync_len, var->upper_margin, var->lower_margin); -+ -+ fbi->time0 = FARADAY_LCDTIME0_HFP(var->left_margin) -+ | FARADAY_LCDTIME0_HBP(var->right_margin) -+ | FARADAY_LCDTIME0_HW(var->hsync_len) -+ | FARADAY_LCDTIME0_PL(var->xres); -+ -+ fbi->time1 = FARADAY_LCDTIME1_VBP(var->upper_margin) -+ | FARADAY_LCDTIME1_VFP(var->lower_margin) -+ | FARADAY_LCDTIME1_VW(var->vsync_len) -+ | FARADAY_LCDTIME1_LF(var->yres); -+ -+ if ((plcd->Timing0 != fbi->time0) -+ || (plcd->Timing1 != fbi->time1) -+ || (plcd->Timing2 != fbi->time2) -+ || (plcd->Control != fbi->control)) { -+ -+ faradayfb_schedule_work(info, C_REENABLE); -+ } -+ -+ return 0; -+} -+ -+/* Set the user defined part of the display for the specified console */ -+static int faradayfb_set_par(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ struct fb_var_screeninfo *var = &info->var; -+ unsigned long palette_mem_size; -+ -+ if (var->bits_per_pixel == 16 || var->bits_per_pixel == 32) -+ info->fix.visual = FB_VISUAL_TRUECOLOR; -+ else if (!fbi->cmap_static) -+ info->fix.visual = FB_VISUAL_PSEUDOCOLOR; -+ else { -+ /* -+ * Some people have weird ideas about wanting static -+ * pseudocolor maps. I suspect their user space -+ * applications are broken. -+ */ -+ info->fix.visual = FB_VISUAL_STATIC_PSEUDOCOLOR; -+ } -+ -+ info->fix.line_length = var->xres_virtual * var->bits_per_pixel / 8; -+ -+ fbi->palette_size = var->bits_per_pixel == 8 ? 256 : 16; -+ -+ palette_mem_size = fbi->palette_size * sizeof(u32); -+ -+ DEBUG(0, 1, "info->fix.line_length = %d\n", info->fix.line_length); -+ DEBUG(0, 1, "palette_mem_size = 0x%08lx\n", (unsigned long) palette_mem_size); -+ -+ fbi->palette_cpu = (u32 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); -+ -+ fbi->palette_dma = fbi->map_dma + PAGE_SIZE - palette_mem_size; -+ -+ /* Set (any) board control register to handle new color depth */ -+ faradayfb_activate_var(var, info); -+ -+ DEBUG(0, 1, "Leave\n"); -+ -+ return 0; -+} -+ -+static irqreturn_t faradayfb_handle_irq(int irq, void *dev_id) -+{ -+#if 0 -+ struct fb_info *info = (struct fb_info*)dev_id; -+ struct faradayfb_info *fbi = info->par; -+ volatile LCD_Register *plcd = (LCD_Register *)fbi->io_base; -+ u32 status = plcd->Interrupt; -+#endif -+ return IRQ_HANDLED; -+} -+ -+/* -+ * This function must be called from task context only, since it will -+ * sleep when disabling the LCD controller, or if we get two contending -+ * processes trying to alter state. -+ */ -+static void set_ctrlr_state(struct fb_info *info, unsigned int state) -+{ -+ struct faradayfb_info *fbi = info->par; -+ unsigned int old_state; -+ -+ down(&fbi->ctrlr_sem); -+ -+ old_state = fbi->state; -+ -+ /* Hack around fbcon initialisation. */ -+ if (old_state == C_STARTUP && state == C_REENABLE) -+ state = C_ENABLE; -+ -+ switch (state) { -+ case C_DISABLE_PM: -+ case C_DISABLE: -+ -+ /* Disable controller */ -+ if (old_state != C_DISABLE) { -+ -+ fbi->state = state; -+ faradayfb_disable_int(info); -+ faradayfb_lcd_power(info, 0); -+ // faradayfb_disable_controller(info); -+ } -+ break; -+ -+ case C_REENABLE: -+ /* -+ * Re-enable the controller only if it was already -+ * enabled. This is so we reprogram the control -+ * registers. -+ */ -+ if (old_state == C_ENABLE) { -+ -+ faradayfb_disable_int(info); -+ faradayfb_lcd_power(info, 0); -+ faradayfb_disable_controller(info); -+ -+ faradayfb_setup_gpio(info); -+ faradayfb_lcd_power(info, 1); -+ faradayfb_enable_controller(info); -+ faradayfb_enable_int(info); -+ } -+ break; -+ -+ case C_ENABLE_PM: -+ /* -+ * Re-enable the controller after PM. This is not -+ * perfect - think about the case where we were doing -+ * a clock change, and we suspended half-way through. -+ */ -+ if (old_state != C_DISABLE_PM) -+ break; -+ /* fall through */ -+ -+ case C_ENABLE: -+ /* -+ * Power up the LCD screen, enable controller, and -+ * turn on the backlight. -+ */ -+ if (old_state != C_ENABLE) { -+ -+ fbi->state = C_ENABLE; -+ faradayfb_setup_gpio(info); -+ faradayfb_lcd_power(info, 1); -+ faradayfb_enable_controller(info); -+ faradayfb_enable_int(info); -+ } -+ break; -+ } -+ up(&fbi->ctrlr_sem); -+} -+ -+/* -+ * Blank the display by setting all palette values to zero. Note, the -+ * 12 and 16 bpp modes don't really use the palette, so this will not -+ * blank the display in all modes. -+ */ -+static int faradayfb_blank(int blank, struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ int i; -+ -+ switch (blank) { -+ case FB_BLANK_POWERDOWN: -+ case FB_BLANK_VSYNC_SUSPEND: -+ case FB_BLANK_HSYNC_SUSPEND: -+ case FB_BLANK_NORMAL: -+ -+ if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR || -+ info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) { -+ -+ for (i = 0; i < fbi->palette_size; i++) -+ faradayfb_setpalettereg(i, 0, 0, 0, 0, info); -+ } -+ -+ faradayfb_schedule_work(info, C_DISABLE); -+ -+ break; -+ -+ case FB_BLANK_UNBLANK: -+ -+ if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR || -+ info->fix.visual == FB_VISUAL_STATIC_PSEUDOCOLOR) -+ fb_set_cmap(&info->cmap, info); -+ -+ faradayfb_schedule_work(info, C_ENABLE); -+ -+ break; -+ } -+ -+ return 0; -+} -+ -+/* -+ * Our LCD controller task (which is called when we blank or unblank) -+ * via keventd. -+ */ -+static void faradayfb_task(struct work_struct *dummy) -+{ -+ struct faradayfb_info *fbi = container_of(dummy, struct faradayfb_info, task); -+ struct fb_info *info = fbi->info; -+ unsigned int state; -+ -+ state = xchg(&fbi->task_state, -1); -+ set_ctrlr_state(info, state); -+} -+ -+/* Fake monspecs to fill in fbinfo structure */ -+static struct fb_monspecs monspecs = { -+ -+ .hfmin = 30000, -+ .hfmax = 70000, -+ .vfmin = 50, -+ .vfmax = 65, -+}; -+ -+static int ffb_get_mach_param(struct faradayfb_mach_info *inf, struct fb_info *info, unsigned long smode) -+{ -+ struct faradayfb_info *fbi = info->par; -+ struct lcd_param *tparam; -+ unsigned long bpp_mode; -+ -+ if (!(tparam = get_lcd_time(inf->time0, inf->num_time0, smode))) -+ return -1; -+ -+ fbi->time0 = tparam->value; -+ -+ if (!(tparam = get_lcd_time(inf->time1, inf->num_time1, smode))) -+ return -1; -+ -+ fbi->time1 = tparam->value; -+ -+ if (!(tparam = get_lcd_time(inf->time2, inf->num_time2, smode))) -+ return -1; -+ -+ fbi->time2 = tparam->value; -+ -+ switch(info->var.bits_per_pixel) { -+ -+ case 1: case 2: case 4: case 8: -+ bpp_mode = FFB_MODE_8BPP; -+ break; -+ -+ case 16: -+ bpp_mode = FFB_MODE_16BPP; -+ break; -+ -+ case 32: -+ bpp_mode = FFB_MODE_24BPP; -+ break; -+ -+ default: -+ DEBUG(1, 1, "Unsupported BPP, set default BPP to 16\n"); -+ bpp_mode = FFB_MODE_16BPP; -+ break; -+ } -+ -+ if (!(tparam = get_lcd_ctrl(inf->control, inf->num_control, smode | bpp_mode))) -+ return -1; -+ -+ fbi->control = tparam->value; -+ -+ fbi->xres = inf->xres; -+ fbi->yres = inf->yres; -+ -+ return 0; -+} -+ -+static int faradayfb_set_var(struct fb_info *info, struct faradayfb_mach_info *inf, unsigned long type) -+{ -+ struct faradayfb_info *fbi = info->par; -+ unsigned long t_smode = 0; -+ -+ if (!type) -+ t_smode = fbi->smode; -+ else -+ t_smode = type; -+ -+ if (ffb_get_mach_param(inf, info, t_smode)) { -+ -+ DEBUG(1, 1, "Not support mode(%lx)\n", t_smode); -+ return -1; -+ } -+ -+ info->var.xres = fbi->xres; -+ info->var.xres_virtual = fbi->xres; -+ info->var.yres = fbi->yres; -+ info->var.yres_virtual = fbi->yres; -+ -+ info->var.upper_margin = FARADAY_LCDTIME1_GET_VBP(fbi->time1); -+ info->var.lower_margin = FARADAY_LCDTIME1_GET_VFP(fbi->time1); -+ info->var.vsync_len = FARADAY_LCDTIME1_GET_VW(fbi->time1); -+ info->var.left_margin = FARADAY_LCDTIME0_GET_HFP(fbi->time0); -+ info->var.right_margin = FARADAY_LCDTIME0_GET_HBP(fbi->time0); -+ info->var.hsync_len = FARADAY_LCDTIME0_GET_HW(fbi->time0); -+ -+ fbi->int_mask = 0; -+ -+ if (t_smode & FFB_MODE_YUV420) -+ fbi->frame420_size = (((info->var.xres * info->var.yres + 0xffff) & 0xffff0000) >> 16) << 2; -+ else -+ fbi->frame420_size = 0; -+ -+ return 0; -+} -+ -+static struct fb_ops faradayfb_ops = { -+ -+ .owner = THIS_MODULE, -+ .fb_check_var = faradayfb_check_var, -+ .fb_set_par = faradayfb_set_par, -+ .fb_setcolreg = faradayfb_setcolreg, -+ .fb_fillrect = cfb_fillrect, -+ .fb_copyarea = cfb_copyarea, -+ .fb_imageblit = cfb_imageblit, -+ .fb_blank = faradayfb_blank, -+ .fb_mmap = faradayfb_mmap, -+ .fb_ioctl = faradayfb_ioctl, -+}; -+ -+static struct fb_info * __init faradayfb_init_fbinfo(struct device *dev) -+{ -+ struct faradayfb_mach_info *inf; -+ struct fb_info *info; -+ struct faradayfb_info *fbi; -+ -+ if (!(info = framebuffer_alloc(sizeof(struct faradayfb_info), dev))) -+ return NULL; -+ -+ fbi = info->par; -+ fbi->info = info; -+ -+ fbi->io_base = LCD_FTLCDC100_0_VA_BASE; -+ strcpy(info->fix.id, FARADAYFB_MODULE_NAME); -+ -+ info->fix.type = FB_TYPE_PACKED_PIXELS; -+ info->fix.type_aux = 0; -+ info->fix.xpanstep = 0; -+ info->fix.ypanstep = 0; -+ info->fix.ywrapstep = 0; -+ info->fix.accel = FB_ACCEL_NONE; -+ -+ info->var.nonstd = 0; -+ info->var.activate = FB_ACTIVATE_NOW; -+ info->var.height = -1; -+ info->var.width = -1; -+ info->var.accel_flags = 0; -+ info->var.vmode = FB_VMODE_NONINTERLACED; -+ -+ info->fbops = &faradayfb_ops; -+ info->flags = FBINFO_DEFAULT; -+ info->monspecs = monspecs; -+ info->pseudo_palette = &faradayfb_pseudo_palette; -+ -+ fbi->rgb[RGB_8] = &def_rgb_8; -+ fbi->rgb[RGB_16] = &def_rgb_16; -+ fbi->rgb[RGB_24] = &def_rgb_24; -+ -+ inf = (struct faradayfb_mach_info*)dev->platform_data; -+ -+ /* -+ * People just don't seem to get this. We don't support -+ * anything but correct entries now, so panic if someone -+ * does something stupid. -+ */ -+ -+ fbi->xres = inf->xres; -+ fbi->yres = inf->yres; -+ fbi->max_bpp = 32; -+#if defined(CONFIG_FFB_MODE_8BPP) -+ info->var.bits_per_pixel = min((u32)8, inf->max_bpp); -+#elif defined(CONFIG_FFB_MODE_16BPP) -+ info->var.bits_per_pixel = min((u32)16, inf->max_bpp); -+#elif defined(CONFIG_FFB_MODE_24BPP) -+ info->var.bits_per_pixel = min((u32)32, inf->max_bpp); -+ info->var.bits_per_pixel = 32; -+#endif -+ -+ info->var.pixclock = inf->pixclock; -+ info->var.sync = inf->sync; -+ info->var.grayscale = inf->cmap_greyscale; -+ fbi->cmap_inverse = inf->cmap_inverse; -+ fbi->cmap_static = inf->cmap_static; -+ -+ fbi->smode = FFB_DEFAULT_MODE; -+ -+ if (faradayfb_set_var(info, inf, 0)) -+ goto err; -+ -+ fbi->state = C_STARTUP; -+ fbi->task_state = (unsigned char) - 1; -+ info->fix.smem_len = faradayfb_cal_frame_buf_size(fbi); -+ -+ init_waitqueue_head(&fbi->ctrlr_wait); -+ INIT_WORK(&fbi->task, faradayfb_task); -+ init_MUTEX(&fbi->ctrlr_sem); -+ -+ return info; -+err: -+ kfree(fbi); -+ kfree(info); -+ -+ return NULL; -+} -+ -+static int faradayfb_probe(struct platform_device *pdev) -+{ -+ struct fb_info *info; -+ struct faradayfb_info *fbi; -+ int irq; -+ int ret = 0; -+ -+ ret = -ENOMEM; -+ -+ if (!(info = faradayfb_init_fbinfo(&pdev->dev))) { -+ -+ DEBUG(1, 1, "unable to allocate memory for device info\n"); -+ goto err_exit; -+ } -+ -+ fbi = info->par; -+ -+ /* Initialize video memory */ -+ if ((ret = faradayfb_map_video_memory(info)) < 0) -+ goto err_free_mem; -+ -+ ret = -EINVAL; -+ -+ if ((irq = platform_get_irq(pdev, 0)) <= 0) -+ goto err_free_map; -+ -+ if (request_irq(irq, faradayfb_handle_irq, IRQF_DISABLED, "LCD", info)) { -+ -+ DEBUG(1, 1, "request_irq failed: %d\n", ret); -+ goto err_free_map; -+ } -+ -+ /* -+ * This makes sure that our colour bitfield -+ * descriptors are correctly initialised. -+ */ -+ faradayfb_check_var(&info->var, info); -+ faradayfb_set_par(info); -+ -+ dev_set_drvdata(&pdev->dev, info); -+ -+// <============================================ -+ if ((ret = register_framebuffer(info)) < 0) { -+ -+ DEBUG(1, 1, "register_framebuffer failed\n"); -+ goto err_free_irq; -+ } -+// <============================================ -+ -+ faradayfb_clean_screen(info); -+ -+ return 0; -+ -+err_free_irq: -+ dev_set_drvdata(&pdev->dev, NULL); -+ free_irq(irq, info); -+err_free_map: -+ faradayfb_unmap_video_memory(info); -+err_free_mem: -+ kfree(info->par); -+ kfree(info); -+err_exit: -+ return ret; -+} -+ -+/* Called when the device is being detached from the driver */ -+static int faradayfb_remove(struct platform_device *pdev) -+{ -+ struct fb_info *info = platform_get_drvdata(pdev); -+ int irq; -+ -+ set_ctrlr_state(info, C_DISABLE); -+ -+ irq = platform_get_irq(pdev, 0); -+ free_irq(irq, info); -+ -+ unregister_framebuffer(info); -+ faradayfb_unmap_video_memory(info); -+ dev_set_drvdata(&pdev->dev, NULL); -+ kfree(info->par); -+ kfree(info); -+ -+ return 0; -+} -+ -+#ifdef CONFIG_PM -+ -+/* suspend and resume support for the lcd controller */ -+static int faradayfb_suspend(struct platform_device *pdev, pm_message_t mesg) -+{ -+ struct fb_info *info = platform_get_drvdata(pdev); -+ -+ // if (level == SUSPEND_DISABLE || level == SUSPEND_POWER_DOWN) -+ if (mesg.event == PM_EVENT_PRETHAW || mesg.event & PM_EVENT_SLEEP) -+ set_ctrlr_state(info, C_DISABLE_PM); -+ -+ return 0; -+} -+ -+static int faradayfb_resume(struct platform_device *pdev) -+{ -+ struct fb_info *info = platform_get_drvdata(pdev); -+ -+ // need modify -+ // if (level == RESUME_ENABLE) -+ set_ctrlr_state(info, C_ENABLE_PM); -+ -+ return 0; -+} -+ -+#else -+#define faradayfb_suspend NULL -+#define faradayfb_resume NULL -+#endif -+ -+static struct resource faradayfb_resource[] = { -+ -+ { -+ .start = LCD_FTLCDC100_0_PA_BASE, -+ .end = LCD_FTLCDC100_0_PA_LIMIT, -+ .flags = IORESOURCE_MEM, -+ }, -+ { -+ .start = LCD_FTLCDC100_0_IRQ, -+ .end = LCD_FTLCDC100_0_IRQ, -+ .flags = IORESOURCE_IRQ, -+ } -+}; -+ -+static u64 faradayfb_dmamask = ~(u32)0; -+ -+static struct platform_device faradayfb_device = { -+ -+ .name = "faraday-lcd", -+ .id = -1, -+ .num_resources = ARRAY_SIZE(faradayfb_resource), -+ .resource = faradayfb_resource, -+ .dev = { -+ -+ .platform_data = &ffb_mach_info, -+ .dma_mask = &faradayfb_dmamask, -+ .coherent_dma_mask = 0xffffffff, -+ } -+}; -+ -+static struct platform_driver faradayfb_driver = { -+ .probe = faradayfb_probe, -+ .remove = faradayfb_remove, -+ .suspend = faradayfb_suspend, -+ .resume = faradayfb_resume, -+ .driver = { -+ .name = "faraday-lcd", -+ }, -+}; -+ -+/* -+rick note faraday driver -+*/ -+ -+/* Register both the driver and the device */ -+int __init faradayfb_init(void) -+{ -+ int ret = 0; -+ /* Register the device with LDM */ -+ -+#if 1 -+ if (platform_device_register(&faradayfb_device)) { -+ -+ DEBUG(1, 1, "failed to register faradayfb device\n"); -+ ret = -ENODEV; -+ goto exit; -+ } -+#endif -+ /* Register the driver with LDM */ -+ if (platform_driver_register(&faradayfb_driver)) { -+ -+ DEBUG(1, 1, "failed to register faradayfb driver\n"); -+ platform_device_unregister(&faradayfb_device); -+ ret = -ENODEV; -+ goto exit; -+ } -+exit: -+ return ret; -+} -+ -+static void __exit faradayfb_cleanup(void) -+{ -+ platform_driver_unregister(&faradayfb_driver); -+ platform_device_unregister(&faradayfb_device); -+} -+ -+module_init(faradayfb_init); -+module_exit(faradayfb_cleanup); -+MODULE_DESCRIPTION("Faraday LCD driver"); -+MODULE_AUTHOR("Francis Huang "); -+MODULE_LICENSE("GPL"); -diff -Nur linux-3.4.113.orig/drivers/video/FTLCDC100/Kconfig linux-3.4.113/drivers/video/FTLCDC100/Kconfig ---- linux-3.4.113.orig/drivers/video/FTLCDC100/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/video/FTLCDC100/Kconfig 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1,74 @@ -+config FB_FTLCDC100 -+ tristate "Faraday FTLCDC100 driver" -+ depends on FB && NDS32 -+ select FB_CFB_FILLRECT -+ select FB_CFB_COPYAREA -+ select FB_CFB_IMAGEBLIT -+ -+ choice -+ prompt "Default LCD Panel" -+ depends on FB_FTLCDC100 -+ default PANEL_AUA036QN01 -+ help -+ This option select a default panel setting for the LCD controller -+ -+ config PANEL_AUA036QN01 -+ bool "AU 3.5 inch LCD Panel" -+ -+ config PANEL_CH7013A -+ bool "Chrontel Digital PC to TV Encoder" -+ select I2C -+ select I2C_FARADAY -+ select CH7013A -+ -+ config PANEL_AUA070VW04 -+ bool "AU 7.0 inch LCD Panel" -+ -+ config PANEL_LW500AC9601 -+ bool "CHIMEI 5.0 inch LCD panel" -+ -+ endchoice -+ -+ # config FTLCD_OSD -+ # bool "Enable OSD (On Screen Display)" -+ # depends on FB_FTLCDC100 -+ # default n -+ # ---help--- -+ # This enables access to the OSD (On Screen Display) for Faraday -+ # FTLCDC100 LCD control. Disabling OSD will reduce the size of -+ # the kernel by approximately 6kb. -+ # -+ -+ choice -+ prompt "Default Color Mode" -+ depends on FB_FTLCDC100 -+ default FFB_MODE_RGB -+ help -+ This option select default color mode -+ -+ config FFB_MODE_RGB -+ bool "RGB Mode" -+ config FFB_MODE_YUV422 -+ bool "YUV422 Mode" -+ config FFB_MODE_YUV420 -+ bool "YUV420 Mode" -+ endchoice -+ -+ choice -+ prompt "Default BPP" -+ depends on FB_FTLCDC100 -+ default FFB_MODE_16BPP -+ help -+ This option select default BPP (bits-per-pixel) -+ -+ config FFB_MODE_8BPP -+ depends on FFB_MODE_RGB || FFB_MODE_YUV420 -+ bool "8 bits-per-pixel" -+ config FFB_MODE_16BPP -+ depends on FFB_MODE_RGB || FFB_MODE_YUV422 -+ bool "16 bits-per-pixel" -+ config FFB_MODE_24BPP -+ depends on FFB_MODE_RGB -+ bool "24 bits-per-pixel" -+ endchoice -+ -diff -Nur linux-3.4.113.orig/drivers/video/FTLCDC100/lcd-info.c linux-3.4.113/drivers/video/FTLCDC100/lcd-info.c ---- linux-3.4.113.orig/drivers/video/FTLCDC100/lcd-info.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/video/FTLCDC100/lcd-info.c 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1,264 @@ -+/* -+ * HBP : Horizontal Back Porch -+ * HFP : Horizontal Front Porch -+ * HSPW: Horizontal Sync. Pulse Width -+ * PPL : Pixels-per-line = 16(PPL+1) -+ */ -+#define ENC_PARAM_TIME0(HBP, HFP, HSPW, PPL) \ -+ ((((HBP) - 1) << 24) | \ -+ (((HFP) - 1) << 16) | \ -+ (((HSPW) - 1) << 8 ) | \ -+ ((((PPL) >> 4) - 1) << 2 )) -+ -+/* -+ * HBP : Vertical Back Porch -+ * HFP : Vertical Front Porch -+ * HSPW: Vertical Sync. Pulse Width -+ * LPP : Lines-per-panel = LPP + 1 -+ */ -+#define ENC_PARAM_TIME1(VBP, VFP, VSPW, LPP) \ -+ ((((VBP) ) << 24) | \ -+ (((VFP) ) << 16) | \ -+ (((VSPW) - 1) << 10) | \ -+ (((LPP) - 1) )) -+ -+/* -+ * PRA : Pixel Rate Adaptive -+ * IOE : Invert Panel Output Enable -+ * IPC : Invert Panel Clock (Test Chip Testing) -+ * IHS : Invert Horisontal Sync. -+ * IVS : Invert Versical Sync. -+ * PCD : Panel Clock Divisor -+ */ -+#define ENC_PARAM_TIME2(PRA, IOE, IPC, IHS, IVS, PCD) \ -+ (((PRA) << 15) | \ -+ ((IOE) << 14) | \ -+ ((IPC) << 13) | \ -+ ((IHS) << 12) | \ -+ ((IVS) << 11) | \ -+ (((PCD) - 1) )) -+ -+/* -+ * Enable YCbCr -+ * Enable YCbCr420 -+ * FIFO threadhold -+ * Panel type, 0-6bit, 1-8bit -+ * LcdVComp, when to generate interrupt, 1: start of back_porch -+ * Power Enable -+ * Big Endian Pixel/Byte Ordering -+ * BGR -+ * TFT -+ * LCD bits per pixel -+ * Controller Enable -+ */ -+ -+#define ENC_PARAM_CTRL(ENYUV, ENYUV420, FIFOTH, PTYPE, VCOMP, LCD_ON, ENDIAN, BGR, TFT, BPP, LCD_EN) \ -+ ((ENYUV << 18) | \ -+ (ENYUV420 << 17) | \ -+ (FIFOTH << 16) | \ -+ (PTYPE << 15) | \ -+ (VCOMP << 12) | \ -+ (LCD_ON << 11) | \ -+ (ENDIAN << 9) | \ -+ (BGR << 8) | \ -+ (TFT << 5) | \ -+ (BPP << 1) | \ -+ (LCD_EN)) -+ -+static struct lcd_param control[] = { -+ -+ { -+ .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x3, 1), -+ .flags = FFB_MODE_RGB | FFB_MODE_8BPP, -+ }, -+ { -+ .value = ENC_PARAM_CTRL(1, 1, 1, 1, 0x3, 1, 0x0, 0, 1, 0x3, 1), -+ .flags = FFB_MODE_YUV420 | FFB_MODE_8BPP, -+ }, -+ { -+ .value = ENC_PARAM_CTRL(1, 0, 1, 1, 0x3, 1, 0x0, 0, 1, 0x4, 1), -+ .flags = FFB_MODE_YUV422 | FFB_MODE_16BPP, -+ }, -+ { -+ .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x4, 1), -+ .flags = FFB_MODE_RGB | FFB_MODE_16BPP, -+ }, -+ { -+ .value = ENC_PARAM_CTRL(0, 0, 1, 1, 0x3, 1, 0x0, 1, 1, 0x5, 1), -+ .flags = FFB_MODE_RGB | FFB_MODE_24BPP, -+ }, -+}; -+ -+#ifdef CONFIG_PANEL_AUA036QN01 -+ -+static struct lcd_param time0[] = { -+ -+ { -+ .value = ENC_PARAM_TIME0(7, 6, 1, 320), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct lcd_param time1[] = { -+ -+ { -+ .value = ENC_PARAM_TIME1(1, 1, 1, 240), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct lcd_param time2[] = { -+ -+ { -+ .value = ENC_PARAM_TIME2(0, 0, 1, 1, 1, 0x7), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct faradayfb_mach_info ffb_mach_info = { -+ -+ .pixclock = 171521, -+ .xres = 320, -+ .yres = 240, -+ .max_bpp = 24, -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ .num_time0 = ARRAY_SIZE(time0), -+ .time0 = time0, -+ .num_time1 = ARRAY_SIZE(time1), -+ .time1 = time1, -+ .num_time2 = ARRAY_SIZE(time2), -+ .time2 = time2, -+ .num_control = ARRAY_SIZE(control), -+ .control = control, -+}; -+#endif -+ -+#ifdef CONFIG_PANEL_AUA070VW04 -+static struct lcd_param time0[] = { -+ -+ { -+ .value = ENC_PARAM_TIME0(88, 40, 128, 800), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct lcd_param time1[] = { -+ -+ { -+ .value = ENC_PARAM_TIME1(21, 1, 3, 480), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct lcd_param time2[] = { -+ -+ { -+ .value = ENC_PARAM_TIME2(0, 1, 1, 1, 1, 0x5), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct faradayfb_mach_info ffb_mach_info = { -+ -+ .pixclock = 171521, -+ .xres = 800, -+ .yres = 480, -+ .max_bpp = 24, -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ .num_time0 = ARRAY_SIZE(time0), -+ .time0 = time0, -+ .num_time1 = ARRAY_SIZE(time1), -+ .time1 = time1, -+ .num_time2 = ARRAY_SIZE(time2), -+ .time2 = time2, -+ .num_control = ARRAY_SIZE(control), -+ .control = control, -+}; -+ -+#endif -+ -+#ifdef CONFIG_PANEL_LW500AC9601 -+static struct lcd_param time0[] = { -+ -+ { -+ .value = ENC_PARAM_TIME0(88, 40, 128, 800), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct lcd_param time1[] = { -+ -+ { -+ .value = ENC_PARAM_TIME1(21, 1, 3, 480), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct lcd_param time2[] = { -+ -+ { -+ .value = ENC_PARAM_TIME2( 0, 0, 1, 1, 1, 0x3), -+ .flags = FFB_MODE_RGB | FFB_MODE_YUV420 | FFB_MODE_YUV422, -+ }, -+}; -+ -+static struct faradayfb_mach_info ffb_mach_info = { -+ -+ .pixclock = 171521, -+ .xres = 800, -+ .yres = 480, -+ .max_bpp = 24, -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ .num_time0 = ARRAY_SIZE(time0), -+ .time0 = time0, -+ .num_time1 = ARRAY_SIZE(time1), -+ .time1 = time1, -+ .num_time2 = ARRAY_SIZE(time2), -+ .time2 = time2, -+ .num_control = ARRAY_SIZE(control), -+ .control = control, -+}; -+#endif -+ -+#ifdef CONFIG_CH7013A -+static struct lcd_param time0[] = { -+ -+ { -+ .value = ENC_PARAM_TIME0(42, 10, 96, 640), -+ .flags = FFB_MODE_RGB, -+ }, -+}; -+ -+static struct lcd_param time1[] = { -+ -+ { -+ .value = ENC_PARAM_TIME1(28, 5, 2, 480), -+ .flags = FFB_MODE_RGB, -+ }, -+}; -+static struct lcd_param time2[] = { -+ -+ { -+ .value = ENC_PARAM_TIME2(0, 1, 1, 0, 0, 0x3), -+ .flags = FFB_MODE_RGB, -+ }, -+}; -+ -+static struct faradayfb_mach_info ffb_mach_info = { -+ -+ .pixclock = 37910, -+ .xres = 640, -+ .yres = 480, -+ .max_bpp = 24, -+ .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, -+ .num_time0 = ARRAY_SIZE(time0), -+ .time0 = time0, -+ .num_time1 = ARRAY_SIZE(time1), -+ .time1 = time1, -+ .num_time2 = ARRAY_SIZE(time2), -+ .time2 = time2, -+ .num_control = ARRAY_SIZE(control), -+ .control = control, -+}; -+ -+#endif /* CONFIG_CH7013A */ -diff -Nur linux-3.4.113.orig/drivers/video/FTLCDC100/Makefile linux-3.4.113/drivers/video/FTLCDC100/Makefile ---- linux-3.4.113.orig/drivers/video/FTLCDC100/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/video/FTLCDC100/Makefile 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1 @@ -+obj-$(CONFIG_FB_FTLCDC100) += faradayfb-main.o -diff -Nur linux-3.4.113.orig/drivers/video/FTLCDC100/pingpong-module.c linux-3.4.113/drivers/video/FTLCDC100/pingpong-module.c ---- linux-3.4.113.orig/drivers/video/FTLCDC100/pingpong-module.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/video/FTLCDC100/pingpong-module.c 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1,592 @@ -+void *fmem_alloc(size_t size, dma_addr_t *dma_handle, unsigned long flags) -+{ -+ struct page *page; -+ void *cpu_addr = NULL; -+ -+ size = PAGE_ALIGN(size); -+ -+ if (!(page = alloc_pages(GFP_DMA, get_order(size)))) { -+ -+ DEBUG(1, 1, "alloc_pages fail! (requested %#x)", size); -+ goto no_page; -+ } -+ -+ *dma_handle = page_to_phys(page); -+ -+ if ((cpu_addr = __ioremap(*dma_handle, size, flags, 1))) { -+ -+ do { -+ SetPageReserved(page); -+ page++; -+ } while (size -= PAGE_SIZE); -+ } -+ else { -+ __free_pages(page, get_order(size)); -+ DEBUG(1, 1, "__ioremap fail! (phy %#x)", *dma_handle); -+ } -+no_page: -+ return cpu_addr; -+} -+ -+void fmem_free(size_t size, void *cpu_addr, dma_addr_t handle) -+{ -+ struct page *page = pfn_to_page(handle >> PAGE_SHIFT); -+ -+ __iounmap(cpu_addr); -+ size = PAGE_ALIGN(size); -+ -+ do { -+ ClearPageReserved(page); -+ __free_page(page); -+ page++; -+ -+ } while (size -= PAGE_SIZE); -+} -+ -+static int faradayfb_mmap(struct fb_info *info, struct vm_area_struct *vma) -+{ -+ struct faradayfb_info *fbi = info->par; -+ unsigned long off = vma->vm_pgoff << PAGE_SHIFT; -+ int ret = -EINVAL; -+ -+ DEBUG(0, 1, "Enter\n"); -+ -+ if (off < info->fix.smem_len) { -+ -+ off += fbi->screen_dma & PAGE_MASK; -+ vma->vm_pgoff = off >> PAGE_SHIFT; -+ vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); -+ vma->vm_flags |= VM_RESERVED; -+ ret = remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, -+ vma->vm_end - vma->vm_start, vma->vm_page_prot); -+ } -+ else { -+ DEBUG(1, 1, "buffer mapping error !!\n"); -+ } -+ -+ DEBUG(0, 1, "Leave\n"); -+ -+ return ret; -+} -+ -+/* -+ * Allocates the DRAM memory for the frame buffer. This buffer is -+ * remapped into a non-cached, non-buffered, memory region to -+ * allow palette and pixel writes to occur without flushing the -+ * cache. Once this area is remapped, all virtual memory -+ * access to the video memory should occur at the new region. -+ */ -+static int __init faradayfb_map_video_memory(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ -+ /* -+ * We reserve one page for the palette, plus the size -+ * of the framebuffer. -+ */ -+ fbi->map_size = PAGE_ALIGN(info->fix.smem_len + PAGE_SIZE); -+ -+ fbi->map_cpu = fmem_alloc(fbi->map_size, &fbi->map_dma, pgprot_writecombine(PAGE_KERNEL)); -+ // fbi->map_cpu = dma_alloc_writecombine(fbi->info->dev, fbi->map_size, &fbi->map_dma, GFP_KERNEL); -+ -+ if (fbi->map_cpu) { -+ -+ memset(fbi->map_cpu, 0x1d, fbi->map_size); -+ info->screen_base = fbi->map_cpu + PAGE_SIZE; -+ fbi->screen_dma = fbi->map_dma + PAGE_SIZE; -+ info->fix.smem_start = fbi->screen_dma; -+ } -+ -+ return fbi->map_cpu ? 0 : -ENOMEM; -+} -+ -+static inline void faradayfb_clean_screen(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ int size = info->var.xres * info->var.yres; -+ -+ if (fbi->smode & FFB_MODE_YUV422) { -+ -+ memset(fbi->map_cpu, 16, size * info->var.bits_per_pixel / 8); -+ } -+ else if (fbi->smode & FFB_MODE_YUV420) { -+ -+ memset(fbi->map_cpu, 16, size); -+ memset(fbi->map_cpu + PAGE_SIZE + ((size + 0xffff) & 0xffff0000), 128, size / 4); -+ memset(fbi->map_cpu + PAGE_SIZE + ((size + 0xffff) & 0xffff0000) * 5 / 4, 128, size / 4); -+ } -+} -+ -+static inline void faradayfb_unmap_video_memory(struct fb_info *info) -+{ -+ struct faradayfb_info *fbi = info->par; -+ fmem_free(fbi->map_size, fbi->map_cpu, fbi->map_dma); -+} -+ -+#define FRAME_SIZE_RGB(xres, yres, mbpp) ((xres) * (yres) * (mbpp) / 8) -+#define FRAME_SIZE_YUV422(xres, yres, mbpp) (((xres) * (yres) * (mbpp) / 8) * 2) -+#define FRAME_SIZE_YUV420(xres, yres, mbpp) (((((xres) * (yres) * (mbpp) / 8) + 0xffff) & 0xffff0000) * 3 / 2) -+ -+static inline u32 faradayfb_cal_frame_buf_size(struct faradayfb_info *fbi) -+{ -+ u32 size_rgb = FRAME_SIZE_RGB(fbi->xres, fbi->yres, fbi->max_bpp); -+ u32 size_yuv422 = FRAME_SIZE_YUV422(fbi->xres, fbi->yres, 8); -+ u32 size_yuv420 = FRAME_SIZE_YUV420(fbi->xres, fbi->yres, 8); -+ -+ return max(size_rgb, max(size_yuv422, size_yuv420)); -+} -+ -+#ifdef CONFIG_FTLCD_OSD -+/************************************ -+ * OSD -+ ***********************************/ -+#define FOSD_SETPOS 0x46e1 -+#define FOSD_SETDIM 0x46e2 -+#define FOSD_SETSCAL 0x46e3 -+#define FLCD_SET_TRANSPARENT 0x46e4 -+#define FLCD_SET_STRING 0x46e5 -+#define FOSD_ON 0x46e6 -+#define FOSD_OFF 0x46e7 -+#define FRREG 0x46e8 -+#define FWREG 0x46e9 -+ -+#define dig_alpha (16 * 10) + (16 * 26) + (16 * 3) -+ -+struct fosd_string { -+ -+ unsigned int Str_row; -+ unsigned int display_mode; -+ unsigned int fg_color; -+ unsigned int bg_color; -+ unsigned char Str_OSD[30]; -+}; -+ -+struct fosd_data { -+ -+ unsigned int HPos; -+ unsigned int VPos; -+ unsigned int HDim; -+ unsigned int VDim; -+ unsigned int transparent_level; -+ unsigned int HScal; -+ unsigned int VScal; -+ struct fosd_string Str_Data[10]; -+}; -+ -+unsigned int OSD_Font[] = { -+ -+ /* 0 */ -+ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x67, 0x6f, 0x7b, -+ 0x73, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 1 */ -+ 0x00, 0x00, 0x00, 0x0c, 0x1c, 0x3c, 0x0c, 0x0c, -+ 0x0c, 0x0c, 0x0c, 0x3f, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 2 */ -+ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x03, 0x06, 0x0c, -+ 0x18, 0x30, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 3 */ -+ 0x00, 0x00, 0x00, 0x3E, 0x63, 0x03, 0x03, 0x1e, -+ 0x03, 0x03, 0x63, 0x3E, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 4 */ -+ 0x00, 0x00, 0x00, 0x06, 0x0e, 0x1e, 0x36, 0x66, -+ 0x7f, 0x06, 0x06, 0x0f, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 5 */ -+ 0x00, 0x00, 0x00, 0x7f, 0x60, 0x60, 0x60, 0x7e, -+ 0x03, 0x03, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 6 */ -+ 0x00, 0x00, 0x00, 0x1c, 0x30, 0x60, 0x60, 0x7e, -+ 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 7 */ -+ 0x00, 0x00, 0x00, 0x7f, 0x63, 0x03, 0x06, 0x0c, -+ 0x18, 0x18, 0x18, 0x18, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 8 */ -+ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3e, -+ 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* 9 */ -+ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x3f, -+ 0x03, 0x03, 0x06, 0x3c, 0x00, 0x00, 0x00, 0x00, -+ -+ /* A */ -+ 0x00, 0x00, 0x00, 0x08, 0x1c, 0x36, 0x63, 0x63, -+ 0x7f, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, -+ -+ /* B */ -+ 0x00, 0x00, 0x00, 0x7E, 0x33, 0x33, 0x33, 0x3E, -+ 0x33, 0x33, 0x33, 0x7E, 0x00, 0x00, 0x00, 0x00, -+ -+ /* C */ -+ 0x00, 0x00, 0x00, 0x1E, 0x33, 0x61, 0x60, 0x60, -+ 0x60, 0x61, 0x33, 0x1E, 0x00, 0x00, 0x00, 0x00, -+ -+ /* D */ -+ 0x00, 0x00, 0x00, 0x7c, 0x36, 0x33, 0x33, 0x33, -+ 0x33, 0x33, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00, -+ -+ /* E */ -+ 0x00, 0x00, 0x00, 0x7f, 0x33, 0x31, 0x34, 0x3c, -+ 0x34, 0x31, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00, -+ -+ /* F */ -+ 0x00, 0x00, 0x00, 0x7f, 0x33, 0x31, 0x34, 0x3c, -+ 0x34, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, -+ -+ /* G */ -+ 0x00, 0x00, 0x00, 0x1E, 0x33, 0x61, 0x60, 0x60, -+ 0x6F, 0x63, 0x36, 0x7C, 0x00, 0x00, 0x00, 0x00, -+ -+ /* H */ -+ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x64, 0x7f, -+ 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, -+ -+ /* I */ -+ 0x00, 0x00, 0x00, 0x3c, 0x18, 0x18, 0x18, 0x18, -+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, -+ -+ /* J */ -+ 0x00, 0x00, 0x00, 0x0f, 0x06, 0x06, 0x06, 0x06, -+ 0x06, 0x66, 0x66, 0x3c, 0x00, 0x00, 0x00, 0x00, -+ -+ /* K */ -+ 0x00, 0x00, 0x00, 0x73, 0x33, 0x36, 0x36, 0x3c, -+ 0x36, 0x36, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00, -+ -+ /* L */ -+ 0x00, 0x00, 0x00, 0x78, 0x30, 0x30, 0x30, 0x30, -+ 0x30, 0x31, 0x33, 0x7f, 0x00, 0x00, 0x00, 0x00, -+ -+ /* M */ -+ 0x00, 0x00, 0x00, 0x63, 0x77, 0x7f, 0x6b, 0x63, -+ 0x63, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, -+ -+ /* N */ -+ 0x00, 0x00, 0x00, 0x63, 0x73, 0x7b, 0x7f, 0x6f, -+ 0x67, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, -+ -+ /* O */ -+ 0x00, 0x00, 0x00, 0x1c, 0x36, 0x63, 0x63, 0x63, -+ 0x63, 0x63, 0x36, 0x1c, 0x00, 0x00, 0x00, 0x00, -+ -+ /* P */ -+ 0x00, 0x00, 0x00, 0x7e, 0x33, 0x33, 0x33, 0x3e, -+ 0x30, 0x30, 0x30, 0x78, 0x00, 0x00, 0x00, 0x00, -+ -+ /* Q */ -+ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x63, 0x63, -+ 0x6b, 0x6f, 0x3e, 0x06, 0x07, 0x00, 0x00, 0x00, -+ -+ /* R */ -+ 0x00, 0x00, 0x00, 0x7e, 0x33, 0x33, 0x33, 0x3e, -+ 0x36, 0x33, 0x33, 0x73, 0x00, 0x00, 0x00, 0x00, -+ -+ /* S */ -+ 0x00, 0x00, 0x00, 0x3e, 0x63, 0x63, 0x30, 0x1c, -+ 0x06, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* T */ -+ 0x00, 0x00, 0x00, 0xFF, 0x99, 0x18, 0x18, 0x18, -+ 0x18, 0x18, 0x18, 0x3c, 0x00, 0x00, 0x00, 0x00, -+ -+ /* U */ -+ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, -+ 0x63, 0x63, 0x63, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* V */ -+ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, -+ 0x63, 0x36, 0x1c, 0x08, 0x00, 0x00, 0x00, 0x00, -+ -+ /* W */ -+ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x63, 0x63, -+ 0x6b, 0x7f, 0x77, 0x63, 0x00, 0x00, 0x00, 0x00, -+ -+ /* X */ -+ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1c, -+ 0x36, 0x63, 0x63, 0x63, 0x00, 0x00, 0x00, 0x00, -+ -+ /* Y */ -+ 0x00, 0x00, 0x00, 0x63, 0x63, 0x63, 0x36, 0x1c, -+ 0x1c, 0x1c, 0x1c, 0x3e, 0x00, 0x00, 0x00, 0x00, -+ -+ /* Z */ -+ 0x00, 0x00, 0x00, 0x7f, 0x63, 0x46, 0x0c, 0x18, -+ 0x30, 0x61, 0x63, 0x7f, 0x00, 0x00, 0x00, 0x00, -+ -+ /* space */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ -+ /* = */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7E, 0x00, -+ 0x00, 0x7E, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ -+ /* , */ -+ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, -+ 0x00, 0x18, 0x18, 0x18, 0x30, 0x00, 0x00, 0x00, -+}; -+ -+void OSD_On(struct faradayfb_info *fbi) -+{ -+ REG32(fbi->io_base + 0x34) &= 0xfffffffe; -+ REG32(fbi->io_base + 0x34) |= 1; -+} -+ -+void OSD_Off(struct faradayfb_info *fbi) -+{ -+ REG32(fbi->io_base + 0x34) &= 0xfffffffe; -+} -+ -+void OSD_Pos(struct faradayfb_info *fbi, int HPos, int VPos) -+{ -+ REG32(fbi->io_base + 0x38) = (HPos << 10) | VPos; -+} -+ -+void OSD_Dim(struct faradayfb_info *fbi, int HDim, int VDim) -+{ -+ REG32(fbi->io_base + 0x34) &= 0x0000001f; -+ REG32(fbi->io_base + 0x34) |= ((HDim << 10) | (VDim << 5)); -+} -+ -+void OSD_transparent(struct faradayfb_info *fbi, int level) -+{ -+ REG32(fbi->io_base + 0x40) &= 0xffffff00; -+ REG32(fbi->io_base + 0x40) |= (level << 6); -+} -+ -+void OSD_fg_color(struct faradayfb_info *fbi, int pal0, int pal1, int pal2, int pal3) -+{ -+ REG32(fbi->io_base + 0x3c) = (pal0) | (pal1 << 8) | (pal2 << 16) | (pal3<< 24); -+} -+ -+void OSD_bg_color(struct faradayfb_info *fbi, int pal1, int pal2, int pal3) -+{ -+ REG32(fbi->io_base + 0x40) &= 0x000000ff; -+ REG32(fbi->io_base + 0x40) |= (pal1 << 8) | (pal2 << 16) | (pal3 << 24); -+} -+ -+void OSD_Scal(struct faradayfb_info *fbi, int HScal, int VScal) -+{ -+ REG32(fbi->io_base + 0x34) &= 0xffffffe1; -+ REG32(fbi->io_base + 0x34) |= (HScal << 3) | (VScal << 1); -+} -+ -+void OSD_putc(struct faradayfb_info *fbi, char c, int position, unsigned int value) -+{ -+ if (c >= '0' && c <= '9') -+ REG32(fbi->io_base + 0xc000 + position * 4) = ((c -'0') << 4) | value; -+ -+ else if (c>= 'A' && c <= 'Z') -+ REG32(fbi->io_base + 0xc000 + position * 4) = ((c - 'A' + 10) << 4) | value; -+ -+ if (c == ' ') -+ REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 1) << 4) | value; -+ -+ if (c == '=') -+ REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 2) << 4) | value; -+ -+ if (c == ',') -+ REG32(fbi->io_base + 0xc000 + position * 4) = (('Z' - 'A' + 10 + 3) << 4) | value; -+} -+ -+void OSD_puts(struct faradayfb_info *fbi, char *str, int position, unsigned int value) -+{ -+ int i; -+ -+ for (i = 0; i < strlen(str); i++) -+ OSD_putc(fbi, *(str + i), position + i, value); -+} -+ -+void OSD_String(struct faradayfb_info *fbi, int row, int mode, char *str, int fg_color, int bg_color) -+{ -+ int i, j, x, y; -+ unsigned int value = fg_color | bg_color; -+ -+ /* 10 digit & 26 alphabet & ' ' & '=' & ',' */ -+ for (i = 0; i < dig_alpha; i++) { -+ -+ x = 0; -+ y = OSD_Font[i]; -+ -+ for (j = 0; j < 12; j ++) { /* reorder */ -+ if (y & 1) -+ x |= 1; -+ y >>= 1; -+ x <<= 1; -+ } -+ -+ x >>= 1; -+ REG32(fbi->io_base + 0x8000 + i * 4) = x; -+ } -+ -+ OSD_puts(fbi, str, row, value); -+ -+ if (mode == 2) { /* YCbCr */ -+ -+ OSD_fg_color(fbi, 0x57, 0x88, 0x3B, 0xFF); -+ OSD_bg_color(fbi, 0x57, 0x88, 0x3B); -+ } -+ else { -+ OSD_fg_color(fbi, 0x07, 0x38, 0xC0, 0xFF); -+ OSD_bg_color(fbi, 0x07, 0x38, 0xc0); -+ } -+} -+#endif /* CONFIG_FTLCD_OSD */ -+ -+struct andesIO { -+ -+ unsigned long Regaddr; -+ unsigned long Regoffset; -+ unsigned long Regvalue; -+}; -+ -+static int faradayfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) -+{ -+ int ret = 0; -+#ifdef CONFIG_FTLCD_OSD -+ struct faradayfb_info *fbi = info->par; -+ int i; -+ struct fosd_data fosd; -+ -+ struct andesIO IOAccess; -+ unsigned long *Regaccess; -+#endif -+ -+ DEBUG(0, 1, "Enter\n"); -+ -+ switch (cmd) { -+#ifdef CONFIG_FTLCD_OSD -+ case FRREG: -+ -+ if (copy_from_user(&IOAccess, (struct andesIO *)arg, sizeof(struct andesIO))) { -+ -+ ret = -EFAULT; -+ break; -+ } -+ -+ Regaccess = (unsigned long *)(((IOAccess.Regaddr >> 4) | (unsigned long)0xF0000000) + IOAccess.Regoffset); -+ -+ IOAccess.Regvalue = *(Regaccess); -+ -+ if (copy_to_user((struct andesIO *)arg, &IOAccess, sizeof(struct andesIO))) { -+ ret = -EFAULT; -+ break; -+ } -+ -+ break; -+ -+ case FWREG: -+ -+ if (copy_from_user(&IOAccess, (struct andesIO *)arg, sizeof(struct andesIO))) { -+ ret = -EFAULT; -+ break; -+ } -+ -+ Regaccess = (unsigned long *)(((IOAccess.Regaddr >> 4) | (unsigned long)0xF0000000) + IOAccess.Regoffset); -+ *(Regaccess) = IOAccess.Regvalue; -+ -+ break; -+ -+ case FOSD_ON: -+ -+ DEBUG(1, 1, "FOSD_ON:\n"); -+ OSD_On(fbi); -+ break; -+ -+ case FOSD_OFF: -+ -+ DEBUG(1, 1, "FOSD_OFF:\n"); -+ OSD_Off(fbi); -+ break; -+ -+ case FOSD_SETPOS: -+ -+ DEBUG(1, 1, "FOSD_SETPOS:\n"); -+ -+ if (copy_from_user(&fosd, (unsigned int *)arg, 2 * sizeof(unsigned int))) { -+ -+ ret = -EFAULT; -+ break; -+ } -+ -+ OSD_Pos(fbi, fosd.HPos, fosd.VPos); -+ DEBUG(1, 1, "OSD_Pos = %d %d\n", fosd.HPos, fosd.VPos); -+ break; -+ -+ case FOSD_SETDIM: -+ -+ DEBUG(1, 1, "FOSD_SETDIM:\n"); -+ -+ if (copy_from_user(&fosd, (unsigned int *)arg, 4 * sizeof(unsigned int))) { -+ -+ ret = -EFAULT; -+ break; -+ } -+ -+ OSD_Dim(fbi, fosd.HDim, fosd.VDim); -+ DEBUG(1, 1, "OSD_Dim = %d %d\n", fosd.HDim, fosd.VDim); -+ break; -+ -+ case FOSD_SETSCAL: -+ -+ DEBUG(1, 1, "FOSD_SETSCAL:\n"); -+ -+ if (copy_from_user(&fosd, (unsigned int *)arg, 7 * sizeof(unsigned int))) { -+ ret = -EFAULT; -+ break; -+ } -+ -+ OSD_Scal(fbi, fosd.HScal, fosd.VScal); -+ break; -+ -+ case FLCD_SET_TRANSPARENT: -+ -+ DEBUG(1, 1, "FLCD_SET_TRANSPARENT:\n"); -+ -+ if (copy_from_user(&fosd, (unsigned int *)arg, 5 * sizeof(unsigned int))) { -+ -+ ret = -EFAULT; -+ break; -+ } -+ -+ OSD_transparent(fbi, fosd.transparent_level); -+ DEBUG(1, 1, "OSD_transparent = %d\n", fosd.transparent_level); -+ break; -+ -+ case FLCD_SET_STRING: -+ -+ DEBUG(1, 1, "FLCD_SET_STRING:\n"); -+ -+ if (copy_from_user(&fosd, (unsigned int *)arg, sizeof(struct fosd_data))) { -+ -+ ret = -EFAULT; -+ break; -+ } -+ -+ for (i = 0; i < fosd.VDim; i++) -+ -+ OSD_String(fbi, fosd.Str_Data[i].Str_row, -+ fosd.Str_Data[i].display_mode, -+ fosd.Str_Data[i].Str_OSD, -+ fosd.Str_Data[i].fg_color, -+ fosd.Str_Data[i].bg_color); -+ break; -+#endif /* CONFIG_FTLCD_OSD */ -+ -+ default: -+ -+ DEBUG(1, 1, "IOCTL CMD(0x%08u) no define!\n", cmd); -+ ret = -EFAULT; -+ break; -+ } -+ -+ DEBUG(0, 1, "Leave\n"); -+ return ret; -+} -+ -diff -Nur linux-3.4.113.orig/drivers/video/Kconfig linux-3.4.113/drivers/video/Kconfig ---- linux-3.4.113.orig/drivers/video/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/video/Kconfig 2016-12-01 20:59:24.392614293 +0100 -@@ -2166,6 +2166,8 @@ - ---help--- - Say Y here to enable support for PNX4008 RGB Framebuffer - -+source "drivers/video/FTLCDC100/Kconfig" -+ - config FB_IBM_GXT4500 - tristate "Framebuffer support for IBM GXT4500P adaptor" - depends on FB && PPC -diff -Nur linux-3.4.113.orig/drivers/video/Makefile linux-3.4.113/drivers/video/Makefile ---- linux-3.4.113.orig/drivers/video/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/video/Makefile 2016-12-01 20:59:24.392614293 +0100 -@@ -143,6 +143,7 @@ - obj-$(CONFIG_FB_CARMINE) += carminefb.o - obj-$(CONFIG_FB_MB862XX) += mb862xx/ - obj-$(CONFIG_FB_MSM) += msm/ -+obj-$(CONFIG_FB_FTLCDC100) += FTLCDC100/ - obj-$(CONFIG_FB_NUC900) += nuc900fb.o - obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o - obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o -diff -Nur linux-3.4.113.orig/drivers/watchdog/ftwdt010_wdt.c linux-3.4.113/drivers/watchdog/ftwdt010_wdt.c ---- linux-3.4.113.orig/drivers/watchdog/ftwdt010_wdt.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/drivers/watchdog/ftwdt010_wdt.c 2016-12-01 20:59:24.392614293 +0100 -@@ -0,0 +1,127 @@ -+/* -+ * Watchdog driver for the FTWDT010 Watch Dog Driver -+ * -+ * (c) Copyright 2004 Faraday Technology Corp. (www.faraday-tech.com) -+ * Based on sa1100_wdt.c by Oleg Drokin -+ * Based on SoftDog driver by Alan Cox -+ * -+ * 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. -+ * -+ * 27/11/2004 Initial release -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#define DEBUG( str, ...) \ -+ do{ \ -+ if( debug) \ -+ printk( str, ##__VA_ARGS__); \ -+ } while(0) -+ -+#define wdcounter (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x00)) -+#define wdload (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x04)) -+#define wdrestart (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x08)) -+#define wdcr (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x0C)) -+#define wdstatus (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x10)) -+#define wdclear (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x14)) -+#define wdintrcter (*( volatile unsigned long *)( WDT_FTWDT010_VA_BASE + 0x18)) -+ -+#define TIMER_MARGIN 60 /* (secs) Default is 1 minute */ -+#define RESTART_MAGIC 0x5AB9 -+#define PCLK (AHB_CLK_IN / 2) -+ -+static int debug = 0; -+static int timeout = TIMER_MARGIN; /* in seconds */ -+ -+module_param(debug, int, 0); -+module_param(timeout, int, 0); -+ -+static int ftwdt010_dog_open(struct inode *inode, struct file *file){ -+ -+#if 0 -+ /* Allow only one person to hold it open */ -+ if( test_and_set_bit( 1, &ftwdt010_wdt_users)) -+ return -EBUSY; -+ -+ ftwdt010_wdt_users = 1; -+#endif -+ DEBUG("Activating WDT..\n"); -+ -+ wdcr = 0; -+ wdload = PCLK * timeout; -+ wdrestart = RESTART_MAGIC; /* Magic number */ -+ wdcr = 0x03; /* Enable WDT */ -+ -+ return 0; -+} -+ -+static int ftwdt010_dog_release(struct inode *inode, struct file *file){ -+ -+#ifndef CONFIG_WATCHDOG_NOWAYOUT -+ /* -+ * Shut off the timer. -+ * Lock it in if it's a module and we defined ...NOWAYOUT -+ */ -+ wdcr = 0; -+ DEBUG( "Deactivating WDT..\n"); -+#endif -+ return 0; -+} -+ -+static ssize_t ftwdt010_dog_write(struct file *file, const char *data, size_t len, loff_t *ppos){ -+ -+ if(len){ -+ -+ wdrestart = RESTART_MAGIC; -+ return 1; -+ } -+ -+ return 0; -+} -+ -+static struct file_operations ftwdt010_dog_fops = { -+ -+ .owner = THIS_MODULE, -+ .llseek = no_llseek, -+ .write = ftwdt010_dog_write, -+ .open = ftwdt010_dog_open, -+ .release = ftwdt010_dog_release, -+}; -+ -+static struct miscdevice ftwdt010_dog_miscdev = { -+ -+ WATCHDOG_MINOR, -+ "FTWDT010 watchdog", -+ &ftwdt010_dog_fops -+}; -+ -+static int __init ftwdt010_dog_init( void){ -+ -+ int ret; -+ -+ ret = misc_register(&ftwdt010_dog_miscdev); -+ -+ if( ret) -+ return ret; -+ -+ DEBUG("FTWDT010 watchdog timer: timer timeout %d sec\n", timeout); -+ -+ return 0; -+} -+ -+static void __exit ftwdt010_dog_exit( void){ -+ -+ misc_deregister(&ftwdt010_dog_miscdev); -+} -+ -+module_init(ftwdt010_dog_init); -+module_exit(ftwdt010_dog_exit); -+MODULE_AUTHOR("Faraday Corp."); -+MODULE_LICENSE("GPL"); -diff -Nur linux-3.4.113.orig/drivers/watchdog/Kconfig linux-3.4.113/drivers/watchdog/Kconfig ---- linux-3.4.113.orig/drivers/watchdog/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/watchdog/Kconfig 2016-12-01 20:59:24.392614293 +0100 -@@ -64,6 +64,12 @@ - To compile this driver as a module, choose M here: the - module will be called softdog. - -+config FTWDT010_WATCHDOG -+ tristate "FTWDT010_WATCHDOG" -+ help -+ Support for Faraday ftwdt010 watchdog. When the watchdog triigers the -+ system will be reset. -+ - config WM831X_WATCHDOG - tristate "WM831x watchdog" - depends on MFD_WM831X -diff -Nur linux-3.4.113.orig/drivers/watchdog/Makefile linux-3.4.113/drivers/watchdog/Makefile ---- linux-3.4.113.orig/drivers/watchdog/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/drivers/watchdog/Makefile 2016-12-01 20:59:24.392614293 +0100 -@@ -163,6 +163,7 @@ - obj-$(CONFIG_XEN_WDT) += xen_wdt.o - - # Architecture Independent -+obj-$(CONFIG_FTWDT010_WATCHDOG) += ftwdt010_wdt.o - obj-$(CONFIG_WM831X_WATCHDOG) += wm831x_wdt.o - obj-$(CONFIG_WM8350_WATCHDOG) += wm8350_wdt.o - obj-$(CONFIG_MAX63XX_WATCHDOG) += max63xx_wdt.o -diff -Nur linux-3.4.113.orig/include/linux/mm.h linux-3.4.113/include/linux/mm.h ---- linux-3.4.113.orig/include/linux/mm.h 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/include/linux/mm.h 2016-12-01 20:59:24.392614293 +0100 -@@ -157,6 +157,7 @@ - #define FAULT_FLAG_ALLOW_RETRY 0x08 /* Retry fault if blocking */ - #define FAULT_FLAG_RETRY_NOWAIT 0x10 /* Don't drop mmap_sem and wait when retrying */ - #define FAULT_FLAG_KILLABLE 0x20 /* The fault task is in SIGKILL killable region */ -+#define FAULT_FLAG_TRIED 0x40 /* second try */ - - /* - * This interface is used by x86 PAT code to identify a pfn mapping that is -diff -Nur linux-3.4.113.orig/include/linux/semaphore.h linux-3.4.113/include/linux/semaphore.h ---- linux-3.4.113.orig/include/linux/semaphore.h 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/include/linux/semaphore.h 2016-12-01 20:59:24.392614293 +0100 -@@ -36,6 +36,9 @@ - lockdep_init_map(&sem->lock.dep_map, "semaphore->lock", &__key, 0); - } - -+#define init_MUTEX(sem) sema_init(sem, 1) -+#define init_MUTEX_LOCKED(sem) sema_init(sem, 0) -+ - extern void down(struct semaphore *sem); - extern int __must_check down_interruptible(struct semaphore *sem); - extern int __must_check down_killable(struct semaphore *sem); -diff -Nur linux-3.4.113.orig/init/Kconfig linux-3.4.113/init/Kconfig ---- linux-3.4.113.orig/init/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/init/Kconfig 2016-12-01 20:59:24.392614293 +0100 -@@ -966,7 +966,7 @@ - - config UID16 - bool "Enable 16-bit UID system calls" if EXPERT -- depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) -+ depends on ARM || BLACKFIN || CRIS || FRV || H8300 || X86_32 || M68K || NDS32 || (S390 && !64BIT) || SUPERH || SPARC32 || (SPARC64 && COMPAT) || UML || (X86_64 && IA32_EMULATION) - default y - help - This enables the legacy 16-bit UID syscall wrappers. -diff -Nur linux-3.4.113.orig/kernel/Makefile linux-3.4.113/kernel/Makefile ---- linux-3.4.113.orig/kernel/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/kernel/Makefile 2016-12-01 20:59:24.396614447 +0100 -@@ -20,6 +20,7 @@ - CFLAGS_REMOVE_rtmutex-debug.o = -pg - CFLAGS_REMOVE_cgroup-debug.o = -pg - CFLAGS_REMOVE_irq_work.o = -pg -+CFLAGS_REMOVE_kallsyms.o = -pg - endif - - obj-y += sched/ -diff -Nur linux-3.4.113.orig/kernel/trace/Kconfig linux-3.4.113/kernel/trace/Kconfig ---- linux-3.4.113.orig/kernel/trace/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/kernel/trace/Kconfig 2016-12-01 20:59:24.396614447 +0100 -@@ -141,7 +141,7 @@ - config FUNCTION_TRACER - bool "Kernel Function Tracer" - depends on HAVE_FUNCTION_TRACER -- select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE -+ select FRAME_POINTER if !ARM_UNWIND && !PPC && !S390 && !MICROBLAZE && !NDS32 - select KALLSYMS - select GENERIC_TRACER - select CONTEXT_SWITCH_TRACER -diff -Nur linux-3.4.113.orig/lib/Kconfig.debug linux-3.4.113/lib/Kconfig.debug ---- linux-3.4.113.orig/lib/Kconfig.debug 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/lib/Kconfig.debug 2016-12-01 20:59:24.396614447 +0100 -@@ -615,7 +615,7 @@ - bool - depends on DEBUG_KERNEL && TRACE_IRQFLAGS_SUPPORT && STACKTRACE_SUPPORT && LOCKDEP_SUPPORT - select STACKTRACE -- select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE -+ select FRAME_POINTER if !MIPS && !PPC && !ARM_UNWIND && !S390 && !MICROBLAZE && !NDS32 - select KALLSYMS - select KALLSYMS_ALL - -@@ -1122,7 +1122,7 @@ - depends on FAULT_INJECTION_DEBUG_FS && STACKTRACE_SUPPORT - depends on !X86_64 - select STACKTRACE -- select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND -+ select FRAME_POINTER if !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !NDS32 - help - Provide stacktrace filter for fault-injection capabilities - -@@ -1132,7 +1132,7 @@ - depends on DEBUG_KERNEL - depends on STACKTRACE_SUPPORT - depends on PROC_FS -- select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND -+ select FRAME_POINTER if !MIPS && !PPC && !S390 && !MICROBLAZE && !ARM_UNWIND && !NDS32 - select KALLSYMS - select KALLSYMS_ALL - select STACKTRACE -diff -Nur linux-3.4.113.orig/sound/Kconfig linux-3.4.113/sound/Kconfig ---- linux-3.4.113.orig/sound/Kconfig 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/sound/Kconfig 2016-12-01 20:59:24.396614447 +0100 -@@ -93,6 +93,8 @@ - - source "sound/sh/Kconfig" - -+source "sound/nds32/Kconfig" -+ - # the following will depend on the order of config. - # here assuming USB is defined before ALSA - source "sound/usb/Kconfig" -diff -Nur linux-3.4.113.orig/sound/Makefile linux-3.4.113/sound/Makefile ---- linux-3.4.113.orig/sound/Makefile 2016-10-26 17:15:47.000000000 +0200 -+++ linux-3.4.113/sound/Makefile 2016-12-01 20:59:24.396614447 +0100 -@@ -6,7 +6,7 @@ - obj-$(CONFIG_SOUND_PRIME) += oss/ - obj-$(CONFIG_DMASOUND) += oss/ - obj-$(CONFIG_SND) += core/ i2c/ drivers/ isa/ pci/ ppc/ arm/ sh/ synth/ usb/ \ -- firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ -+ firewire/ sparc/ spi/ parisc/ pcmcia/ mips/ soc/ atmel/ nds32/ - obj-$(CONFIG_SND_AOA) += aoa/ - - # This one must be compilable even if sound is configured out -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_ALSA.c linux-3.4.113/sound/nds32/FTSSP010_ALSA.c ---- linux-3.4.113.orig/sound/nds32/FTSSP010_ALSA.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_ALSA.c 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,2020 @@ -+/* FTSSP010 - UDA1345TS module: -+ * -+ * $log$ -+ * -+ * 2006/02/23: I-Jui Sung: OSS emulation half-duplex -+ * playback/capture at 48K, 44.1K, 8K -+ * with mono/stereo 16bit/8bit -+ * -+ * 2006/02/22: I-Jui Sung: OSS emulation playback at 44.1KHz -+ * 16-bit mono completed. Relying ALSA to -+ * resample -+ * 2009/02/24: dma upgrade checking list: -+ * - ac97 mode playback ................. ok -+ * - ac97 mode capture .................. ok -+ * - i2s mode playback .................. ok -+ * - i2s mode capture ................... ok -+ * - mixer support (snd_ctl_add, ...) ... todo -+ * - debug /proc entry .................. ok -+ */ -+ -+ -+#include -+#include -+#include -+#include -+//#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+ -+#include -+#include -+#include -+#include -+ -+#include "FTSSP010_UDA1345TS.h" -+ -+//ADD by river 2011.06.02 -+struct alc5630_data; -+//End ADD by river 2011.06.02 -+ -+void init_hw(unsigned int cardno,unsigned int ac97, struct i2c_client *client); -+ -+#if (!defined(CONFIG_PLATFORM_AHBDMA) && !defined(CONFIG_PLATFORM_APBDMA)) -+#warning needs ahb/apb dma to wrok -+#endif -+ -+/* --------------------------------------------------------------------------- -+ * Define the debug level of FTSSP_DEBUG -+ */ -+#define FTSSP_DEBUG 0 -+#define FTSSP_DEBUG_VERBOSE 0 -+#define FTSSP_PROC_FS 0 -+ -+#undef VVDBG -+#if (FTSSP_DEBUG_VERBOSE) -+#define VVDBG(vvar...) (void)0 -+//#define VVDBG(vvar...) printk(KERN_INFO vvar) -+#else -+#define VVDBG(vvar...) (void)0 -+#endif -+ -+#undef ERR -+#define ERR(vvar...) printk(KERN_ERR vvar) -+ -+#undef INFO -+#define INFO(vvar...) printk(KERN_INFO vvar) -+ -+#if (FTSSP_DEBUG) -+#undef DBG -+#define DBG(vvar...) printk(KERN_INFO vvar) -+#else -+#define DBG(vvar...) (void)0 -+#endif -+ -+#if (FTSSP_DEBUG_VERBOSE) -+#undef VDBG -+#define VDBG(vvar...) printk(KERN_INFO vvar) -+#else -+#define VDBG(vvar...) (void)0 -+#endif -+ -+#ifdef CONFIG_SND_FTSSP010_I2S -+//ADD by river 2011.02.11 -+static struct i2c_client *g_i2c_client; -+ -+////////// ADD by river 2011.01.26 -+// Each client has this additional data -+struct alc5630_data { -+ struct i2c_client *client; -+ struct delayed_work work; -+ unsigned long gpio2_value; -+ struct mutex mtx; -+}; -+ -+static int alc5630_i2c_attach(struct i2c_adapter *adapter); -+static int alc5630_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id); -+static int alc5630_i2c_suspend(struct i2c_client *i2c_client, pm_message_t mesg); -+static int alc5630_i2c_resume(struct i2c_client *i2c_client); -+ -+static int alc5630_i2c_remove(struct i2c_client *client); -+static int ftssp_alsa_init(struct i2c_client *client); -+ -+ -+static int i2s_alc5630_read(unsigned int raddr, char *data, struct i2c_client *client) -+{ -+ struct i2c_adapter *adap = client->adapter; -+ struct i2c_msg msg; -+ int ret, i2c_value; -+ -+ //Reading ALC5630 register -+ msg.addr = raddr; -+ msg.flags = (client->flags & I2C_M_TEN) | I2C_M_RD; -+ msg.len = 1; -+ msg.buf = (char *)data; -+ -+ //ret = i2c_transfer(adap, &msg, 1); -+ #ifndef CONFIG_SND_FTSSP010_AC97 -+ ret = i2c_transfer(adap, &msg, 1); -+ #endif -+ -+ if (ret != 0) { -+ printk("i2c read failed\n"); -+ return -1; -+ } -+ else -+ { -+ i2c_value = (data[0]&0xff) << 8 | (data[1]&0xff); -+ return i2c_value; -+ } -+ -+} -+ -+static void i2s_alc5630_write(unsigned int addr, unsigned int data, struct i2c_client *client) -+{ -+ -+ struct i2c_adapter *adap = client->adapter; -+ struct i2c_msg msg; -+ int ret, i2c_value; -+ char buf[3]; -+ -+ //Writing ALC5630 register -+ i2c_value = 0x0; -+ msg.addr = addr; -+ msg.flags = (client->flags & I2C_M_TEN) | ~I2C_M_RD; -+ msg.len = 1; -+ -+ buf[0] = (data >> 8) & 0xff; -+ buf[1] = data & 0xff; -+ msg.buf = (char *)buf; -+ -+ //ret = i2c_transfer(adap, &msg, 1); -+ #ifndef CONFIG_SND_FTSSP010_AC97 -+ ret = i2c_transfer(adap, &msg, 1); -+ #endif -+ -+ if (ret != 0) { -+ printk("i2c write failed\n"); -+ } -+ -+} -+ -+static void i2s_alc5630_read_test(struct i2c_client *client) -+{ -+ char data[3]; -+ //printk(">>>>> : i2s_alc5630_read_test().....\n"); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0, i2s_alc5630_read(0x0, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x02, i2s_alc5630_read(0x02, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x04, i2s_alc5630_read(0x04, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x06, i2s_alc5630_read(0x06, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x08, i2s_alc5630_read(0x08, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0a, i2s_alc5630_read(0x0a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0c, i2s_alc5630_read(0x0c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0e, i2s_alc5630_read(0x0e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x10, i2s_alc5630_read(0x10, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x12, i2s_alc5630_read(0x12, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x14, i2s_alc5630_read(0x14, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x16, i2s_alc5630_read(0x16, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x18, i2s_alc5630_read(0x18, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x1a, i2s_alc5630_read(0x1a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x1c, i2s_alc5630_read(0x1c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x1e, i2s_alc5630_read(0x1e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x20, i2s_alc5630_read(0x20, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x22, i2s_alc5630_read(0x22, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x24, i2s_alc5630_read(0x24, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x26, i2s_alc5630_read(0x26, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x28, i2s_alc5630_read(0x28, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x2a, i2s_alc5630_read(0x2a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x2c, i2s_alc5630_read(0x2c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x2e, i2s_alc5630_read(0x2e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x30, i2s_alc5630_read(0x30, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x32, i2s_alc5630_read(0x32, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x34, i2s_alc5630_read(0x34, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x36, i2s_alc5630_read(0x36, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x38, i2s_alc5630_read(0x38, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x3a, i2s_alc5630_read(0x3a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x3c, i2s_alc5630_read(0x3c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x3e, i2s_alc5630_read(0x3e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x40, i2s_alc5630_read(0x40, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x42, i2s_alc5630_read(0x42, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x44, i2s_alc5630_read(0x44, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x46, i2s_alc5630_read(0x46, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x48, i2s_alc5630_read(0x48, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x4a, i2s_alc5630_read(0x4a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x4c, i2s_alc5630_read(0x4c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x4e, i2s_alc5630_read(0x4e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x50, i2s_alc5630_read(0x50, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x52, i2s_alc5630_read(0x52, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x54, i2s_alc5630_read(0x54, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x56, i2s_alc5630_read(0x56, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x58, i2s_alc5630_read(0x58, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x5a, i2s_alc5630_read(0x5a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x5c, i2s_alc5630_read(0x5c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x5e, i2s_alc5630_read(0x5e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x60, i2s_alc5630_read(0x60, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x62, i2s_alc5630_read(0x62, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x64, i2s_alc5630_read(0x64, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x66, i2s_alc5630_read(0x66, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x68, i2s_alc5630_read(0x68, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x6a, i2s_alc5630_read(0x6a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x6c, i2s_alc5630_read(0x6c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x6e, i2s_alc5630_read(0x6e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x70, i2s_alc5630_read(0x70, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x72, i2s_alc5630_read(0x72, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x74, i2s_alc5630_read(0x74, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x76, i2s_alc5630_read(0x76, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x78, i2s_alc5630_read(0x78, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x7a, i2s_alc5630_read(0x7a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x7c, i2s_alc5630_read(0x7c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x7e, i2s_alc5630_read(0x7e, data,client)); -+ -+} -+ -+static int alc5630_i2c_attach(struct i2c_adapter *adapter){ -+ -+ struct i2c_board_info info; -+ struct i2c_client *client; -+ -+ int ret=0; -+ -+ //i2c_dbg( 1, "alc5630_i2c_attach() is called.\n"); -+ //printk(">>>>>>>>>> (2) alc5630_i2c_attach() is called.\n"); -+ -+ //ret = i2c_probe(adapter, &addr_data, alc5630_detect); -+ memset(&info, 0, sizeof(struct i2c_board_info)); -+ strlcpy(info.type, "alc5630_codec", I2C_NAME_SIZE); -+ //info.addr = 0x3e; -+ info.addr = 0x66; -+ //info.platform_data = node; -+ -+ //client = i2c_new_device(adapter, &info); -+ #ifndef CONFIG_SND_FTSSP010_AC97 -+ client = i2c_new_device(adapter, &info); -+ #endif -+ if (!client) { -+ printk("$$$$$????? : i2c_new_device() failed.....\n"); -+ return -ENODEV; -+ } -+ /* -+ * We know the driver is already loaded, so the device should be -+ * already bound. If not it means binding failed, and then there -+ * is no point in keeping the device instantiated. -+ */ -+ if (!client->driver) { -+ //i2c_unregister_device(client); -+ #ifndef CONFIG_SND_FTSSP010_AC97 -+ i2c_unregister_device(client); -+ #endif -+ return -ENODEV; -+ } -+ -+ /* -+ * Let i2c-core delete that device on driver removal. -+ * This is safe because i2c-core holds the core_lock mutex for us. -+ */ -+ list_add_tail(&client->detected, &client->driver->clients); -+ -+ return ret; -+} -+ -+static irqreturn_t gpio2_irq(int irq, void *dev_id) -+{ -+ -+ struct i2c_client *client = (struct i2c_client *)dev_id; -+ struct alc5630_data *alc5630 = i2c_get_clientdata(client); -+ -+ unsigned long org_mask, org_dir; -+ //printk("@@@@@#####$$$$$!!!!! : gpio2_irq is detected ???....\n"); -+ -+ //Mask GPIO interrupt -+ //REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) & ~(1 << 13); //GPIO interrupt disable -+ -+ //Dump AMIC contents and ir~ -+ unsigned long ir0,ir1,ir2, ir3, ir4, ir5; -+ unsigned long ir6, ir7, ir8, ir9, ir10; -+ unsigned long ir11, ir12, ir13, ir14, ir15; -+ unsigned long gpio2_value, value; -+ char data[3]; -+ -+ -+ //__asm__ volatile ("setgie.d\n\t"); -+ //REG32(AMIC_VA_BASE + 0x80) = 0; -+ -+ -+ //Get original gpio direction -+ org_dir = REG32(GPIO_VA_BASE + 0x08); -+ -+ //Get original gpio interrupt mask -+ org_mask = REG32(GPIO_VA_BASE + 0x2c); -+ -+ //Mask all gpio interrupt -+ REG32(GPIO_VA_BASE + 0x2c) = 0x0000FFFF; -+ //Clear all gpio interrupt -+ REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; -+ -+ //Get gpio pin value -+ REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 2); //Set gpio2 direction => input -+ gpio2_value = (REG32(GPIO_VA_BASE + 0x04) >> 2 & 1); -+ //printk("The gpio2 value is 0x%08x\n",gpio2_value); -+ -+ -+ alc5630->gpio2_value = gpio2_value; -+ schedule_delayed_work(&alc5630->work, 1); -+ -+ /*if (gpio3_value==0x1) { -+ i2s_alc5630_write(0x02, 0x0000, g_i2c_client); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0040 , g_i2c_client); -+ printk("External speaker is plugged in... and Try to mute internal speaker......\n"); -+ } -+ else { -+ i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0440 , g_i2c_client); -+ printk("External speaker is pulled ... and Try to unmute internal speaker......\n"); -+ }*/ -+ -+ -+ //Set gpio3 pin value to 0 -+ //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) | (0x1UL << 3); //Set gpio3 direction => output -+ //value = REG32(GPIO_VA_BASE + 0x00) & ~(0x1UL << 3); -+ //REG32(GPIO_VA_BASE + 0x00) = value; -+ -+ //Get gpio pin value again -+ //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 3); //Set gpio3 direction => input -+ //gpio3_value = (REG32(GPIO_VA_BASE + 0x04) >> 3 & 1); -+ //printk("The gpio3 value is 0x%08x\n",gpio3_value); -+ -+ //restore original gpio interrupt mask -+ REG32(GPIO_VA_BASE + 0x2c) = org_mask; -+ -+ //restore original gpio direction -+ REG32(GPIO_VA_BASE + 0x08) = org_dir; -+ -+ //unmask GPIO interrupt -+ //REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) | (1 << 13); //GPIO interrupt enable -+ REG32(AMIC_VA_BASE + 0x84) = REG32(AMIC_VA_BASE + 0x84) | (1 << 13); //Clear GPIO interrupt -+ REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; //Clear all gpio interrupt -+ -+ //printk("@@@@@#####$$$$$!!!!! : gpio2_irq() is exited....\n"); -+ -+ return IRQ_HANDLED; -+} -+ -+static void iic_work(struct work_struct *work) -+{ -+ char data[3]; -+ struct alc5630_data *alc5630 = -+ container_of(to_delayed_work(work), struct alc5630_data, work); -+ -+ -+ if (alc5630->gpio2_value==0x0) { -+ //i2s_alc5630_write(0x02, 0x0000, alc5630->client); -+ i2s_alc5630_write(0x02, 0x5F5F, alc5630->client); -+ i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,alc5630->client) & 0xFBFF) | 0x0040 , alc5630->client); -+ //printk("External speaker is plugged in... and Try to mute internal speaker......\n"); -+ //i2s_alc5630_read_test(alc5630->client); -+ } -+ else { -+ //i2s_alc5630_write(0x02, 0x5F5F, alc5630->client); -+ i2s_alc5630_write(0x02, 0x0000, alc5630->client); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,alc5630->client)|0x0440 , alc5630->client); -+ //printk("External speaker is pulled ... and Try to unmute internal speaker......\n"); -+ //i2s_alc5630_read_test(alc5630->client); -+ } -+ //ftsdc_enable_irq(host, false); -+ -+ -+ //ftsdc_enable_irq(host, true); -+} -+ -+static int alc5630_i2c_probe(struct i2c_client *client, const struct i2c_device_id *id) -+{ -+ -+ struct alc5630_data *alc5630; -+ struct i2c_adapter *adap = client->adapter; -+ //unsigned char ret1, ret2; -+ struct i2c_msg msg; -+ char rbuf[3], wbuf[3]; -+ int ret, i2c_rvalue, i2c_wvalue; -+ unsigned int gpio2_value; -+ char data[3]; -+ -+ //i2c_dbg( 1, "alc5630_i2c_probe() is called.\n"); -+ //printk(">>>>>>>>>> (3) alc5630_i2c_probe() is called.\n"); -+ -+ alc5630 = kzalloc(sizeof(struct alc5630_data), GFP_KERNEL); -+ -+ if (!alc5630) -+ return -ENOMEM; -+ -+ mutex_init(&alc5630->mtx); -+ client-> flags = 0; -+ alc5630->client = client; -+ i2c_set_clientdata(client, alc5630); -+ -+ //ADD by river 2011.05.18 for GPIO2 interrupt => edge trigger and rising edge -+ REG32(GPIO_VA_BASE + 0x20) = 0x00000000; -+ REG32(GPIO_VA_BASE + 0x2c) = 0x00000000; -+ REG32(GPIO_VA_BASE + 0x2c) = 0x00000000; -+ REG32(GPIO_VA_BASE + 0x30) = 0x0000FFFF; -+ REG32(GPIO_VA_BASE + 0x38) = 0x0000FFFF; -+ REG32(GPIO_VA_BASE + 0x40) = 0x0000FFFF; -+ -+ -+ REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(1 << 2); //GPIO2 as input -+ REG32(GPIO_VA_BASE + 0x34) = REG32(GPIO_VA_BASE + 0x34) & ~(1 << 2); //GPIO2 edge trigger -+ //REG32(GPIO_VA_BASE + 0x38) = REG32(GPIO_VA_BASE + 0x38) & ~(1 << 2); //GPIO2 single edge -+ REG32(GPIO_VA_BASE + 0x38) = REG32(GPIO_VA_BASE + 0x38) | (1 << 2); //GPIO2 both edge -+ REG32(GPIO_VA_BASE + 0x3c) = REG32(GPIO_VA_BASE + 0x3c) & ~(1 << 2); //GPIO2 rising edge -+ REG32(GPIO_VA_BASE + 0x20) = REG32(GPIO_VA_BASE + 0x20) | (1 << 2); //GPIO2 pin interrupt enable -+ -+ REG32(AMIC_VA_BASE + 0x20) = REG32(AMIC_VA_BASE + 0x20) | (1 << 13); //Interrupt Trigger Mode (edge trigger) -+ REG32(AMIC_VA_BASE + 0x24) = REG32(AMIC_VA_BASE + 0x24) & ~(1 << 13); //Interrupt Trigger edge(rising edge) -+ REG32(AMIC_VA_BASE + 0x80) = REG32(AMIC_VA_BASE + 0x80) | (1 << 13); //GPIO interrupt enabled -+ //REG32(AMIC_VA_BASE + 0x80) = 0; //GPIO interrupt enabled -+ -+ if (request_irq(GPIO_FTGPIO010_IRQ, gpio2_irq, IRQF_SHARED, "gpio2", client)) { -+ printk("Failed to request GPIO2 interrupt.\n"); -+ goto fail; -+ } -+ -+ //ADD by river 2011.07.11 -+ //REG32(GPIO_VA_BASE + 0x08) = REG32(GPIO_VA_BASE + 0x08) & ~(0x1UL << 3); //Set gpio3 direction => input -+ gpio2_value = (REG32(GPIO_VA_BASE + 0x04) >> 2 & 1); -+ //printk("The gpio2 value is 0x%08x\n",gpio2_value); -+ alc5630->gpio2_value = gpio2_value; -+ -+ if (gpio2_value==0x0) { -+ i2s_alc5630_write(0x02, 0x5F5F, alc5630->client); -+ i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,alc5630->client) & 0xFBFF) | 0x0040 , alc5630->client); -+ //printk("@@@@@ alc5630_i2c_probe : External speaker is plugged in... and Try to mute internal speaker......\n"); -+ //i2s_alc5630_read_test(alc5630->client); -+ } -+ else { -+ i2s_alc5630_write(0x02, 0x0000, alc5630->client); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,alc5630->client)|0x0440 , alc5630->client); -+ //printk("@@@@@ alc5630_i2c_probe : External speaker is pulled ... and Try to unmute internal speaker......\n"); -+ //i2s_alc5630_read_test(alc5630->client); -+ } -+ -+ //End ADD by river 2011.07.11 -+ -+ //ADD by river 2011.06.02 -+ INIT_DELAYED_WORK(&alc5630->work, iic_work); -+ //End ADD by river 2011.06.02 -+ //End ADD by river 2011.05.18 -+ -+ ftssp_alsa_init(client); -+ -+ return 0; -+ fail: -+ mutex_destroy(&alc5630->mtx); -+ kfree(alc5630); -+ return -EINVAL; -+ -+} -+ -+////////End ADD by river 2011.01.26 -+#endif -+ -+/* --------------------------------------------------------------------------- -+ * Preserved size of memory space for audio DMA ring -+ */ -+#define FTSSP_HW_DMA_SIZE (512 * 1024) -+ -+/* Buffer sizes reported to ALSA layer - AC97 mode */ -+ -+/* ring size, exported to application */ -+#define AC97_HW_BUFFER_BYTES_MAX (42 * 1024) -+/* should not exceed AC97_HW_PERIOD_BYTES_MAX */ -+#define AC97_HW_PERIOD_BYTES_MIN (2 * 1024) -+/* AC97_HW_PERIOD_BYTES_MAX * AC97_HW_PERIODS_MAX <= AC97_HW_BUFFER_SIZE */ -+#define AC97_HW_PERIOD_BYTES_MAX (8 * 1024) -+/* 3 <= AC97_HW_PERIODS_MIN <= AC97_HW_PERIODS_MAX */ -+#define AC97_HW_PERIODS_MIN 3 -+/* AC97_HW_PERIOD_BYTES_MAX * AC97_HW_PERIODS_MAX <= AC97_HW_BUFFER_SIZE */ -+#define AC97_HW_PERIODS_MAX 5 -+ -+/* Driver internal dma buffer size, x2 for S16_LE(16-bits) to AC97 (20-bits), -+ * x6 for sampling rate converion from minimum 8k to AC97 48k. -+ * -+ * Note that AC97 mode cannot do playback and recording simultaneouly. So we -+ * use up all FTSSP_HW_DMA_SIZE of memory. -+ */ -+#define AC97_HW_DMA_SIZE (AC97_HW_BUFFER_BYTES_MAX * 2 * 6) -+ -+/* Buffer sizes reported to ALSA layer - I2S mode */ -+ -+/* ring size, exported to application */ -+#define I2S_HW_BUFFER_BYTES_MAX (256 * 1024) -+/* should not exceed I2S_HW_PERIOD_BYTES_MAX */ -+#define I2S_HW_PERIOD_BYTES_MIN (2 * 1024) -+/* I2S_HW_PERIOD_BYTES_MAX * I2S_HW_PERIODS_MAX <= I2S_HW_BUFFER_SIZE */ -+#define I2S_HW_PERIOD_BYTES_MAX (32 * 1024) -+/* 3 <= I2S_HW_PERIODS_MIN <= I2S_HW_PERIODS_MAX */ -+#define I2S_HW_PERIODS_MIN 3 -+/* I2S_HW_PERIOD_BYTES_MAX * I2S_HW_PERIODS_MAX <= I2S_HW_BUFFER_SIZE */ -+#define I2S_HW_PERIODS_MAX 8 -+ -+/* Page-in size for playback and capture each. Note that I2S mode can do -+ * playback and recording simultaneouly, so this size should be less than or -+ * equal to FTSSP_HW_DMA_SIZE/2 -+ */ -+#define I2S_HW_DMA_SIZE (I2S_HW_BUFFER_BYTES_MAX) -+ -+/* --------------------------------------------------------------------------- -+ * Audio formats -+ */ -+#define AC97_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) -+#define AC97_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_48000 | \ -+ SNDRV_PCM_RATE_16000 | \ -+ SNDRV_PCM_RATE_8000) -+#define AC97_CODEC_SAMPLE_RATE_MIN (8000) -+#define AC97_CODEC_SAMPLE_RATE_MAX (48000) -+ -+#define I2S_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) -+#define I2S_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_48000 | \ -+ SNDRV_PCM_RATE_44100 | \ -+ SNDRV_PCM_RATE_32000 | \ -+ SNDRV_PCM_RATE_22050 | \ -+ SNDRV_PCM_RATE_16000 | \ -+ SNDRV_PCM_RATE_11025 | \ -+ SNDRV_PCM_RATE_8000) -+#define I2S_CODEC_SAMPLE_RATE_MIN (8000) -+#define I2S_CODEC_SAMPLE_RATE_MAX (48000) -+ -+ -+/* --------------------------------------------------------------------------- -+ * Configuration -+ */ -+#if (CONFIG_PROC_FS == 0) -+#undef FTSSP_PROC_FS -+#define FTSSP_PROC_FS 0 -+#else -+#if (FTSSP_PROC_FS) -+#include -+#endif /* FTSSP_PROC_FS */ -+#endif /* CONFIG_PROC_FS */ -+ -+#define FTSSP_CARD_ID "ftssp010" -+#define FTSSP_DRIVER_NAME "ftssp" -+ -+MODULE_LICENSE("GPL"); -+MODULE_AUTHOR("Faraday Technology Corp."); -+MODULE_DESCRIPTION("FTSSP010 Linux 2.6 Driver"); -+ -+static int cardno = 0; -+//static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = -+// { SSP_FTSSP010_PA_BASE }; -+ -+/* Driver mode */ -+#ifdef CONFIG_SND_FTSSP010_AC97 -+static int ac97 = 1; -+#else -+static int ac97 = 0; -+#endif -+ -+// ---------------------------------------------- -+module_param(cardno, int, 0); -+MODULE_PARM_DESC(cardno, "FTSSP No."); -+ -+module_param(ac97, int, 0); -+MODULE_PARM_DESC(ac97, "AC97 mode"); -+// ---------------------------------------------- -+ -+/* --------------------------------------------------------------------------- -+ * Structures -+ */ -+ -+/* private data for card */ -+typedef struct { -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ struct snd_pcm_substream *substream_tx; -+ struct snd_pcm_substream *substream_rx; -+#if (FTSSP_PROC_FS) -+ struct snd_info_entry *info_buf_max; -+ struct snd_info_entry *info_period_min; -+ struct snd_info_entry *info_period_max; -+ struct snd_info_entry *info_periods_min; -+ struct snd_info_entry *info_periods_max; -+#endif -+} ftssp_chip; -+ -+/* dma request descriptors */ -+dmad_chreq dma_chreq_tx = { -+ .channel = -1, -+ .drq = NULL, -+}; -+ -+dmad_chreq dma_chreq_rx = { -+ .channel = -1, -+ .drq = NULL, -+}; -+ -+/* Holds ALSA card instance pointers */ -+struct snd_card *ftssp_cards[SSP_FTSSP010_COUNT]; -+ -+/* snd_pcm_hardware */ -+static struct snd_pcm_hardware snd_ftssp_pcm_hw = -+{ -+ .info = SNDRV_PCM_INFO_INTERLEAVED, -+ .formats = I2S_CODEC_FORMATS, -+ .rates = I2S_CODEC_SAMPLE_RATES, -+ .rate_min = I2S_CODEC_SAMPLE_RATE_MIN, -+ .rate_max = I2S_CODEC_SAMPLE_RATE_MAX, -+ .channels_min = 1, -+ .channels_max = 2, -+ .buffer_bytes_max = I2S_HW_BUFFER_BYTES_MAX, -+ .period_bytes_min = I2S_HW_PERIOD_BYTES_MIN, -+ .period_bytes_max = I2S_HW_PERIOD_BYTES_MAX, -+ .periods_min = I2S_HW_PERIODS_MIN, -+ .periods_max = I2S_HW_PERIODS_MAX, -+}; -+ -+/* private data for a substream (playback or capture) */ -+/* function pointer for set up AHBDMA for this substream */ -+typedef void (*start_t)(int cardno, unsigned use_dma); -+typedef void (*pmu_set_clocking_t)(unsigned int); -+typedef void (*ftssp010_config_t)(int cardno, unsigned is_stereo, -+ unsigned speed, int use8bit); -+ -+typedef struct { -+ u32 busy; -+ spinlock_t dma_lock; -+ unsigned dma_area_va; -+ int dma_width; -+ unsigned int tx_period; -+ unsigned int rx_period; -+ -+ start_t start; -+ pmu_set_clocking_t pmu_set_clocking; -+ ftssp010_config_t hw_config; -+} ftssp_substream; -+ -+static ftssp_substream ftssp010_substreams[2] = { -+ /* Playback substream */ -+ { -+ busy : 0, -+ start : ftssp010_start_tx, -+ pmu_set_clocking : pmu_set_i2s_clocking, -+ hw_config : ftssp010_config_tx, -+ }, -+ /* Capture substream */ -+ { -+ busy : 0, -+ start : ftssp010_start_rx, -+ pmu_set_clocking : pmu_set_i2s_clocking, -+ hw_config : ftssp010_config_rx, -+ } -+}; -+ -+/* (AC97 only) Convert 16 bits PCM data in user buffer to/from 20 bits PCM data -+ * (32 bits actaully in dma buffer) for AC97 codec. -+ */ -+static int snd_ftssp_playback_copy(struct snd_pcm_substream *substream, -+ int channel, snd_pcm_uframes_t pos, void *usr_buf, -+ snd_pcm_uframes_t count) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *) runtime->private_data; -+ -+ -+ //printk("~~~~~ : snd_ftssp_playback_copy() is invoked....\n"); -+ u32 *dma_va = NULL; -+ u16 *usr_va = usr_buf; -+ int copy_words; -+ int pcm_data; -+ -+ dmad_chreq *dma_chreq; -+ -+ /* frames_to_bytes(runtime, pos + count) * 2(bytes/per pcm) / -+ * 4(bytes per dma unit) */ -+ u32 sw_ptr = (u32)frames_to_bytes(runtime, pos + count) >> 1; -+ -+ switch (runtime->rate) { -+ case 8000: -+ sw_ptr *= 6; -+ -+ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + -+ frames_to_bytes(runtime, pos * 6) * 2); -+ -+ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", -+ __func__, (u32)pos, (u32)count, (u32)(pos + count)); -+ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", -+ __func__, (u32)ftssp010_substream->dma_area_va, -+ (u32)dma_va, -+ (u32)dma_va + -+ (u32)2 * frames_to_bytes(runtime, count * 6)); -+ -+ if (runtime->channels == 1) { -+ while (count--) { -+ dma_va[0] = (u32)(*usr_va++) << 4; -+ dma_va[1] = dma_va[2] = dma_va[3] = -+ dma_va[4] = dma_va[5] = dma_va[0]; -+ //memcpy(&dma_va[1], &dma_va[0], 5 * 4 * 1); -+ dma_va += 6; -+ } -+ } else { // assume 2 channels -+ while (count--) { -+ dma_va[0] = (u32)(*usr_va++) << 4; -+ dma_va[1] = (u32)(*usr_va++) << 4; -+ dma_va[2] = dma_va[4] = dma_va[6] = -+ dma_va[8] = dma_va[10] = dma_va[0]; -+ dma_va[3] = dma_va[5] = dma_va[7] = -+ dma_va[9] = dma_va[11] = dma_va[0]; -+ //memcpy(&dma_va[2], &dma_va[0], 5 * 4 * 2); -+ dma_va += 12; -+ } -+ } -+ break; -+ case 16000: -+ sw_ptr *= 3; -+ -+ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + -+ frames_to_bytes(runtime, pos * 3) * 2); -+ -+ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", -+ __func__, (u32)pos, (u32)count, (u32)(pos + count)); -+ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", -+ __func__, (u32)ftssp010_substream->dma_area_va, -+ (u32)dma_va, -+ (u32)dma_va + -+ (u32)2 * frames_to_bytes(runtime, count * 3)); -+ -+ if (runtime->channels == 1) { -+ while (count--) { -+ dma_va[0] = (u32)(*usr_va++) << 4; -+ dma_va[1] = dma_va[2] = dma_va[0]; -+ //memcpy(&dma_va[1], &dma_va[0], 2 * 4 * 1); -+ dma_va += 3; -+ } -+ } else { // assume 2 channels -+ while (count--) { -+ dma_va[0] = (u32)(*usr_va++) << 4; -+ dma_va[1] = (u32)(*usr_va++) << 4; -+ dma_va[2] = dma_va[4] = dma_va[0]; -+ dma_va[3] = dma_va[5] = dma_va[1]; -+ //memcpy(&dma_va[2], &dma_va[0], 2 * 4 * 2); -+ dma_va += 6; -+ } -+ } -+ break; -+ case 48000: -+ default: -+ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + -+ frames_to_bytes(runtime, pos) * 2); -+ copy_words = 2 * frames_to_bytes(runtime, count) / sizeof(u32); -+ -+ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", -+ __func__, (u32)pos, (u32)count, (u32)(pos + count)); -+ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", -+ __func__, (u32)ftssp010_substream->dma_area_va, -+ (u32)dma_va, -+ (u32)dma_va + (u32)copy_words*4); -+ -+ while (copy_words--) { -+ pcm_data = (*usr_va++); -+ *dma_va++= pcm_data << 4; -+ } -+ break; -+ } -+ -+ dma_chreq = &dma_chreq_tx; -+ -+ if (dmad_update_ring_sw_ptr(dma_chreq, sw_ptr, -+ (runtime->status->state == SNDRV_PCM_STATE_RUNNING) ? 1:0) != 0) -+ { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ return -ENODEV; -+ } -+ -+ return 0; -+} -+ -+static int snd_ftssp_capture_copy(struct snd_pcm_substream *substream, -+ int channel, snd_pcm_uframes_t pos, void *usr_buf, -+ snd_pcm_uframes_t count) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *) runtime->private_data; -+ -+ //printk("~~~~~ : snd_ftssp_capture_copy() is invoked....\n"); -+ //printk(">>>>>>>>>> : snd_ftssp_capture_copy() for recording....\n"); -+ u32 *dma_va = NULL; -+ u16 *usr_va = usr_buf; -+ -+ switch (runtime->rate) { -+ case 8000: -+ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + -+ frames_to_bytes(runtime, pos * 6) * 2); -+ -+ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", -+ __func__, (u32)pos, (u32)count, (u32)(pos + count)); -+ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", -+ __func__, (u32)ftssp010_substream->dma_area_va, -+ (u32)dma_va, -+ (u32)dma_va + -+ (u32)2 * frames_to_bytes(runtime, count * 6)); -+ -+ if (runtime->channels == 1) { -+ while (count--) { -+ *usr_va++ = (u16)(dma_va[0] >> 4); -+ dma_va += 6; -+ } -+ } else { -+ while (count--) { -+ usr_va[0] = (u16)(dma_va[0] >> 4); -+ -+ /* [hw-limit] only slot-3 has valid data in -+ * recording mode -- check TAG_DATA_MONO -+ * defined in "FTSSP010_lib.c". Mask out -+ * one channel to avoid hi-freq noise. -+ */ -+ usr_va[1] = usr_va[0]; -+ usr_va += 2; -+ dma_va += 12; -+ } -+ } -+ break; -+ case 16000: -+ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + -+ frames_to_bytes(runtime, pos * 3) * 2); -+ -+ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", -+ __func__, (u32)pos, (u32)count, (u32)(pos + count)); -+ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", -+ __func__, (u32)ftssp010_substream->dma_area_va, -+ (u32)dma_va, -+ (u32)dma_va + -+ (u32)2 * frames_to_bytes(runtime, count * 3)); -+ -+ if (runtime->channels == 1) { -+ while (count--) { -+ *usr_va++ = (u16)(dma_va[0] >> 4); -+ dma_va += 3; -+ } -+ } else { -+ while (count--) { -+ usr_va[0] = (u16)(dma_va[0] >> 4); -+ -+ /* [hw-limit] only slot-3 has valid data in -+ * recording mode -- check TAG_DATA_MONO -+ * defined in "FTSSP010_lib.c". Mask out -+ * one channel to avoid hi-freq noise. -+ */ -+ usr_va[1] = usr_va[0]; -+ usr_va += 2; -+ dma_va += 6; -+ } -+ } -+ break; -+ case 48000: -+ default: -+ dma_va = (unsigned *)(ftssp010_substream->dma_area_va + -+ frames_to_bytes(runtime, pos) * 2); -+ -+ VVDBG("%s: pos(0x%08x) count(0x%08x) next_pos(0x%08x)\n", -+ __func__, (u32)pos, (u32)count, (u32)(pos + count)); -+ VVDBG("%s: va base(0x%08x) range (0x%08x ~ 0x%08x)\n", -+ __func__, (u32)ftssp010_substream->dma_area_va, -+ (u32)dma_va, -+ (u32)dma_va + -+ (u32)2 * frames_to_bytes(runtime, count)); -+ -+ if (runtime->channels == 1) { -+ while (count--) { -+ *usr_va++ = (u16)(*dma_va++ >> 4); -+ } -+ } else { -+ while (count--) { -+ usr_va[0] = (u16)(dma_va[0] >> 4); -+ -+ /* [hw-limit] only slot-3 has valid data in -+ * recording mode -- check TAG_DATA_MONO -+ * defined in "FTSSP010_lib.c". Mask out -+ * one channel to avoid hi-freq noise. -+ */ -+ usr_va[1] = usr_va[0]; -+ usr_va += 2; -+ dma_va += 2; -+ } -+ } -+ break; -+ } -+ -+ return 0; -+} -+ -+/** -+ * These dma callbacks are called in interrupt context. -+ * @data: pointer to the chip-wide structure. -+ * TODO: use stream-specifc data -+ */ -+__attribute__((__unused__)) -+static void ftssp_dma_callback_tx(int ch, u16 int_status, void *data) -+{ -+ ftssp_chip *chip = (ftssp_chip *)data; -+ -+ //printk("~~~~~ : ftssp_dma_callback_tx() is invoked....\n"); -+ if (!ac97) { -+ /* in i2s mode, no indication to driver for user data length. -+ * For simplicity, just go ahead by one period */ -+ -+ struct snd_pcm_runtime *runtime = chip->substream_tx->runtime; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)runtime->private_data; -+ u32 sw_ptr; -+ u32 tx_period = ftssp010_substream->tx_period + 1; -+ -+ if (tx_period == runtime->periods) -+ sw_ptr = runtime->buffer_size; -+ else -+ sw_ptr = tx_period * runtime->period_size; -+ -+ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; -+ -+ if (dmad_update_ring_sw_ptr(&dma_chreq_tx, (u32)sw_ptr, 0)) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ } -+ -+ ftssp010_substream->tx_period = tx_period % runtime->periods; -+ } -+ -+ snd_pcm_period_elapsed(chip->substream_tx); -+} -+ -+__attribute__((__unused__)) -+static void ftssp_dma_callback_rx(int ch, u16 int_status, void *data) -+{ -+ ftssp_chip *chip = (ftssp_chip *)data; -+ struct snd_pcm_runtime *runtime = chip->substream_rx->runtime; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)runtime->private_data; -+ -+ //printk("~~~~~ : ftssp_dma_callback_rx() is invoked....\n"); -+ //printk(">>>>>>>>>> : ftssp_dma_callback_rx() for recording....\n"); -+ -+ u32 sw_ptr; -+ u32 rx_period = ftssp010_substream->rx_period + 1; -+ -+ if (rx_period == runtime->periods) -+ sw_ptr = runtime->buffer_size; -+ else -+ sw_ptr = rx_period * runtime->period_size; -+ -+ if (ac97) { -+ switch (runtime->rate) { -+ case 8000: -+ sw_ptr = sw_ptr * 6; -+ break; -+ case 16000: -+ sw_ptr = sw_ptr * 3; -+ break; -+ case 48000: -+ default: -+ break; -+ } -+ } -+ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; -+ -+ if (dmad_update_ring_sw_ptr(&dma_chreq_rx, (u32)sw_ptr, 0) != 0) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ } -+ -+ ftssp010_substream->rx_period = rx_period % runtime->periods; -+ -+ snd_pcm_period_elapsed(chip->substream_rx); -+} -+ -+static inline int snd_ftssp_dma_ch_alloc(struct snd_pcm_substream *substream) -+{ -+ dmad_chreq *ch_req __attribute__((__unused__)) = 0; -+ -+ //printk("~~~~~ WATCH : snd_ftssp_dma_ch_alloc() is invoked....\n"); -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ch_req = &dma_chreq_tx; -+ ch_req->completion_cb = ftssp_dma_callback_tx; -+ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; -+ /*for amerald ac97 ssp2 */ -+ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) -+ { -+ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX_AMERALD; -+ } -+ else -+ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX; -+ } else { -+ ch_req = &dma_chreq_rx; -+ ch_req->completion_cb = ftssp_dma_callback_rx; -+ ch_req->apb_req.tx_dir = DMAD_DIR_A1_TO_A0; -+ /*for amerald ac97 ssp2 */ -+ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) -+ { -+ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX_AMERALD; -+ } -+ else -+ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX; -+ } -+ -+ ch_req->controller = DMAD_DMAC_APB_CORE; -+ ch_req->flags = DMAD_FLAGS_RING_MODE; -+ ch_req->ring_base = 0; -+ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); -+ ch_req->periods = 0; -+ ch_req->period_size = 0; -+ -+ if (ac97) { -+ ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I4X; -+ ch_req->apb_req.ring_reqn = APBBR_REQN_NONE; -+ ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED; -+ ch_req->apb_req.burst_mode = 0; -+ ch_req->apb_req.data_width = APBBR_DATAWIDTH_4; -+ } else { -+ ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I2X; -+ ch_req->apb_req.ring_reqn = APBBR_REQN_NONE; -+ ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED; -+ ch_req->apb_req.burst_mode = 0; -+ ch_req->apb_req.data_width = APBBR_DATAWIDTH_2; -+ } -+ -+ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ ERR("%s: APBDMA channel allocation failed\n",__func__); -+ goto _try_ahb; -+ } -+ -+ DBG("%s: APBDMA channel allocated (ch: %d) ring_mode\n", -+ __func__, ch_req->channel); -+ -+ return 0; -+ -+_try_ahb: -+ -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ch_req = &dma_chreq_tx; -+ ch_req->completion_cb = ftssp_dma_callback_tx; -+ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; -+ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) -+ { -+ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX_AMERALD; -+ } -+ else -+ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX; -+ } else { -+ ch_req = &dma_chreq_rx; -+ ch_req->completion_cb = ftssp_dma_callback_rx; -+ ch_req->ahb_req.tx_dir = DMAD_DIR_A1_TO_A0; -+ if((inl(PMU_BASE) & AMERALD_MASK) == AMERALD_PRODUCT_ID) -+ { -+ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX_AMERALD; -+ } -+ else -+ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX; -+ } -+ -+ ch_req->controller = DMAD_DMAC_AHB_CORE; -+ ch_req->flags = DMAD_FLAGS_RING_MODE; -+ ch_req->ring_base = 0; -+ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); -+ ch_req->periods = 0; -+ ch_req->period_size = 0; -+ -+ ch_req->ahb_req.sync = 1; -+ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_2; -+ ch_req->ahb_req.hw_handshake = 1; -+ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_1; -+ -+ if (ac97) { -+ ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_32; -+ ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC; -+ ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE; -+ ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_32; -+ ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX; -+ } else { -+ ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_16; -+ ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC; -+ ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE; -+ ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_16; -+ ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX; -+ } -+ -+ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ ERR("%s: AHBDMA channel allocation failed\n", __func__); -+ goto _err_exit; -+ } -+ -+ DBG("%s: AHBDMA channel allocated (ch: %d) ring_mode\n", -+ __func__, ch_req->channel); -+ -+ return 0; -+ -+_err_exit: -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+ return -ENODEV; -+} -+ -+static inline ftssp_substream *ftssp010_substream_new(int stream_id) -+{ -+ ftssp_substream *s = NULL; -+ -+ //printk("~~~~~ : ftssp010_substream_new() is invoked....\n"); -+ -+ switch (stream_id) { -+ case SNDRV_PCM_STREAM_PLAYBACK: -+ s = &ftssp010_substreams[0]; -+ break; -+ case SNDRV_PCM_STREAM_CAPTURE: -+ s = &ftssp010_substreams[1]; -+ break; -+ default: -+ ERR("%s: wrong stream type (%d)\n", __func__, stream_id); -+ return NULL; -+ } -+ -+ if (s->busy) { -+ ERR("%s: device busy!\n", __func__); -+ return NULL; -+ } -+ s->busy = 1; -+ -+ spin_lock_init(&s->dma_lock); -+ -+ return s; -+} -+ -+static int snd_ftssp_pcm_open(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ int stream_id = substream->pstr->stream; -+ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ //printk("~~~~~ : snd_ftssp_pcm_open() is invoked....\n"); -+ -+ /* Both playback and capture share a hardware description */ -+ runtime->hw = snd_ftssp_pcm_hw; -+ -+ /* Allocate & Initialize stream-specific data */ -+ runtime->private_data = ftssp010_substream_new(stream_id); -+ -+ if (runtime->private_data) { -+ //printk("~~~~~ YAYAYA @@@@@ : Calling snd_ftssp_dma_ch_alloc().\n"); -+ return snd_ftssp_dma_ch_alloc(substream); -+ } -+ else -+ return -EBUSY; -+} -+ -+static int snd_ftssp_pcm_close(struct snd_pcm_substream *substream) -+{ -+ int stream_id = substream->pstr->stream; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)substream->runtime->private_data; -+ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ //printk("~~~~~ : snd_ftssp_pcm_close() is invoked....\n"); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) -+ dmad_channel_free(&dma_chreq_tx); -+ else -+ dmad_channel_free(&dma_chreq_rx); -+ -+ ftssp010_substream->busy = 0; -+ return 0; -+} -+ -+static int snd_ftssp_pcm_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *hw_params) -+{ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ //printk("~~~~~ : snd_ftssp_pcm_hw_params() is invoked....\n"); -+ -+ if (ac97) -+ return snd_pcm_lib_malloc_pages(substream, AC97_HW_DMA_SIZE); -+ else -+ return snd_pcm_lib_malloc_pages(substream, I2S_HW_DMA_SIZE); -+} -+ -+static int snd_ftssp_pcm_hw_free(struct snd_pcm_substream *substream) -+{ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ //printk("~~~~~ : snd_ftssp_pcm_hw_free() is invoked....\n"); -+ -+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ dmad_drain_requests(&dma_chreq_tx, 1); -+ else -+ dmad_drain_requests(&dma_chreq_rx, 1); -+ -+ return snd_pcm_lib_free_pages(substream); -+} -+ -+/* Prepare FTSSP010 AHBDMA for playback & capture */ -+static int snd_ftssp_pcm_prepare(struct snd_pcm_substream *substream) -+{ -+ ftssp_chip *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ //printk("~~~~~ : snd_ftssp_pcm_prepare() is invoked....\n"); -+ //printk("@@@@@ >>>>> : snd_ftssp_pcm_prepare() is called.\n"); -+ -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)runtime->private_data; -+ -+ int stream_id = substream->pstr->stream; -+ dmad_chreq *dma_chreq; -+ unsigned period_size, buffer_size; -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) -+ dma_chreq = &dma_chreq_tx; -+ else -+ dma_chreq = &dma_chreq_rx; -+ -+ period_size = frames_to_bytes(runtime, runtime->period_size); -+ buffer_size = frames_to_bytes(runtime, runtime->buffer_size); -+ -+ if (runtime->format != SNDRV_PCM_FORMAT_S16_LE) -+ return -ENODEV; -+ -+ if (ac97) { -+ switch (runtime->rate) { -+ case 8000: -+ period_size *= 12; -+ buffer_size *= 12; -+ break; -+ case 16000: -+ period_size *= 6; -+ buffer_size *= 6; -+ break; -+ case 48000: -+ default: -+ period_size *= 2; -+ buffer_size *= 2; -+ break; -+ } -+ -+ ftssp010_substream->dma_width = 4; -+ } else { -+ ftssp010_substream->dma_width = 2; -+ } -+ -+ dmad_drain_requests(dma_chreq, 1); -+ -+ dma_chreq->ring_base = (dma_addr_t)runtime->dma_addr; -+ dma_chreq->periods = (dma_addr_t)runtime->periods; -+ if (ac97) { -+ dma_chreq->period_size = (dma_addr_t)(period_size >> 2); -+ dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 2); -+ } else { -+ dma_chreq->period_size = (dma_addr_t)(period_size >> 1); -+ dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 1); -+ } -+ dmad_update_ring(dma_chreq); -+ -+ /* Set PMU, FTSSP010, and DMA */ -+ spin_lock(&ftssp010_substream->dma_lock); -+ -+ /* keep DMA buffer VA for copy() callback */ -+ // todo: support playback/capture simultaneously -+ ftssp010_substream->dma_area_va = (u32)runtime->dma_area; -+ -+ if (ac97) { -+ ftssp010_substream->pmu_set_clocking(48000); -+ ftssp010_substream->hw_config(cardno, -+ runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */ -+ 48000, ftssp010_substream->dma_width); -+ } else { -+ -+ ftssp010_substream->pmu_set_clocking(runtime->rate); -+ ftssp010_substream->hw_config(cardno, -+ runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */ -+ runtime->rate, ftssp010_substream->dma_width); -+ } -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ ftssp010_substream->tx_period = 0; -+ chip->substream_tx = substream; -+ } else { -+ ftssp010_substream->rx_period = 0; -+ chip->substream_rx = substream; -+ } -+ -+ spin_unlock(&ftssp010_substream->dma_lock); -+ -+ VVDBG("%s <<\n", __func__); -+ -+ return 0; -+} -+ -+static inline int snd_ftssp_start_play(ftssp_substream *ftssp010_substream, -+ struct snd_pcm_runtime *runtime) -+{ -+ int err = 0; -+ -+ //printk("~~~~~ : snd_ftssp_start_play() is invoked....\n"); -+ -+ if (ac97) { -+ /* in ac97 mode, user data was fed to dma buffer through -+ * driver-provided copy callback */ -+ err = dmad_kickoff_requests(&dma_chreq_tx); -+ if (err != 0) { -+ ERR("%s: failed to kickoff dma!\n", __func__); -+ return err; -+ } -+ } else { -+ /* in i2s mode, no indication to driver for user data length -+ * (except start threshold). For simplicity at start, just go -+ * ahead by one cycle */ -+ -+ u32 sw_ptr = -+ (u32)frames_to_bytes(runtime, runtime->buffer_size) >>1; -+ -+ err = dmad_update_ring_sw_ptr(&dma_chreq_tx, sw_ptr, 0); -+ if (err != 0) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ return err; -+ } -+ -+ err = dmad_kickoff_requests(&dma_chreq_tx); -+ if (err != 0) { -+ ERR("%s: failed to kickoff dma!\n", __func__); -+ return err; -+ } -+ } -+ -+ ftssp010_substream->start(cardno, 1); -+ -+ //ADD by river 2011.03.08 -+ //i2s_alc5630_write(0x02, 0x0000, g_i2c_client); -+ //i2s_alc5630_write(0x04, 0x0000, g_i2c_client); -+ //i2s_alc5630_write(0x0c, 0x1010, g_i2c_client); -+ //i2s_alc5630_write(0x10, 0xff03, g_i2c_client); -+ //End ADD by river 2011.03.08 -+ -+ return 0; -+} -+ -+static inline int snd_ftssp_start_record(ftssp_substream *ftssp010_substream, -+ struct snd_pcm_runtime *runtime) -+{ -+ int err = 0; -+ -+ //printk("~~~~~ : snd_ftssp_start_record() is invoked....\n"); -+ -+ u32 sw_ptr = (u32)frames_to_bytes(runtime, runtime->buffer_size); -+ -+ if (ac97) { -+ switch (runtime->rate) { -+ case 8000: -+ sw_ptr = (sw_ptr * 3); -+ break; -+ case 16000: -+ sw_ptr = (sw_ptr * 3) >> 1; -+ break; -+ case 48000: -+ default: -+ sw_ptr = sw_ptr >> 1; -+ break; -+ } -+ } else { -+ -+ //printk(">>>>>>>>>> : snd_ftssp_start_record() for recording....\n"); -+ sw_ptr = sw_ptr >> 1; -+ } -+ -+ err = dmad_update_ring_sw_ptr(&dma_chreq_rx, sw_ptr, 0); -+ if (err != 0) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ return err; -+ } -+ -+ err = dmad_kickoff_requests(&dma_chreq_rx); -+ if (err != 0) { -+ ERR("%s: failed to kickoff dma!\n", __func__); -+ return err; -+ } -+ -+ ftssp010_substream->start(cardno, 1); -+ -+ return 0; -+} -+ -+/* Triggers AHBDMA for playback & capture */ -+static int snd_ftssp_pcm_trigger(struct snd_pcm_substream * substream, int cmd) -+{ -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)substream->runtime->private_data; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ int err = 0; -+ int stream_id = substream->pstr->stream; -+ -+ //printk("~~~~~ : snd_ftssp_pcm_trigger() is invoked....\n"); -+ -+ /* note local interrupts are already disabled in the midlevel code */ -+ spin_lock(&ftssp010_substream->dma_lock); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ -+ VDBG("%s: SNDRV_PCM_TRIGGER_START state(0x%08x)\n", -+ __func__, (u32)runtime->status->state); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ err = snd_ftssp_start_play(ftssp010_substream, runtime); -+ } else { -+ err = snd_ftssp_start_record(ftssp010_substream, -+ runtime); -+ } -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ -+ VDBG("%s: SNDRV_PCM_TRIGGER_STOP state(0x%08x)\n", -+ __func__, (u32)substream->runtime->status->state); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ ftssp010_stop_tx(cardno); -+ dmad_drain_requests(&dma_chreq_tx, 1); -+ } else { -+ ftssp010_stop_rx(cardno); -+ dmad_drain_requests(&dma_chreq_rx, 1); -+ } -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ -+ spin_unlock(&ftssp010_substream->dma_lock); -+ return err; -+} -+ -+// pcm middle-layer call this function within irq (snd_pcm_period_elapsed) or -+// with local irq disabled (snd_pcm_lib_write1) -+static snd_pcm_uframes_t snd_ftssp_pcm_pointer( -+ struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ u32 hw_ptr; -+ snd_pcm_uframes_t ret; -+ int stream_id = substream->pstr->stream; -+ -+ //printk("~~~~~ : snd_ftssp_pcm_pointer() is invoked....\n"); -+ -+ -+ /* Fetch DMA pointer, with spin lock */ -+ //spin_lock_irqsave(&ftssp010_substream->dma_lock, flags); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_tx); -+ } else { -+ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_rx); -+ } -+ -+ //spin_unlock_irqrestore(&ftssp010_substream->dma_lock, flags); -+ -+ if (ac97) { -+ ret = bytes_to_frames(runtime, hw_ptr << 1); -+ -+ switch (runtime->rate) { -+ case 8000: -+ ret = ret / 6; -+ break; -+ case 16000: -+ ret = ret / 3; -+ break; -+ case 48000: -+ default: -+ break; -+ } -+ } else { -+ ret = bytes_to_frames(runtime, hw_ptr << 1); -+ } -+ -+ -+ VVDBG("%s: hw_ptr(0x%08x) ret(0x%08x)\n", -+ (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? "p" : "c", -+ (u32)hw_ptr, (u32)ret); -+ -+ /* ALSA requires return value 0 <= ret < buffer_size */ -+ if (ret >= runtime->buffer_size) -+ return 0; -+ return ret; -+} -+ -+/* For FTSSP010 driver, operations are shared among playback & capture */ -+static struct snd_pcm_ops snd_ftssp_playback_ops = { -+ .open = snd_ftssp_pcm_open, -+ .close = snd_ftssp_pcm_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_ftssp_pcm_hw_params, -+ .hw_free = snd_ftssp_pcm_hw_free, -+ .prepare = snd_ftssp_pcm_prepare, -+ .trigger = snd_ftssp_pcm_trigger, -+ .pointer = snd_ftssp_pcm_pointer, -+ .copy = NULL, -+}; -+ -+static struct snd_pcm_ops snd_ftssp_capture_ops = { -+ .open = snd_ftssp_pcm_open, -+ .close = snd_ftssp_pcm_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_ftssp_pcm_hw_params, -+ .hw_free = snd_ftssp_pcm_hw_free, -+ .prepare = snd_ftssp_pcm_prepare, -+ .trigger = snd_ftssp_pcm_trigger, -+ .pointer = snd_ftssp_pcm_pointer, -+ .copy = NULL, -+}; -+ -+/* ALSA PCM constructor */ -+static int snd_ftssp_new_pcm(ftssp_chip *chip) -+{ -+ struct snd_pcm *pcm; -+ int err; -+ -+ //printk("~~~~~ : snd_ftssp_new_pcm() is invoked....\n"); -+ -+ /* PCM device #0 with 1 playback and 1 capture */ -+ if ((err = snd_pcm_new(chip->card, "ftssp_pcm", 0, 1, 1, &pcm)) < 0) -+ return err; -+ -+ pcm->private_data = chip; -+ strcpy(pcm->name, "ftssp_pcm device"); -+ chip->pcm = pcm; -+ -+ /* set operators for playback and capture*/ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -+ &snd_ftssp_playback_ops); -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, -+ &snd_ftssp_capture_ops); -+ -+ /* Pre-allocate buffer, as suggested by ALSA driver document */ -+ // todo: support playback/capture simultaneously -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ NULL, FTSSP_HW_DMA_SIZE, FTSSP_HW_DMA_SIZE); -+ -+ /* Force half-duplex (on A320D, or AC97 mode) */ -+ if (ac97) -+ pcm->info_flags |= SNDRV_PCM_INFO_HALF_DUPLEX; -+ -+ return 0; -+} -+ -+#if (FTSSP_PROC_FS) -+static void snd_ftssp_buf_max_read(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.buffer_bytes_max); -+} -+ -+static void snd_ftssp_buf_max_write(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ char tmp[128]; -+ char *ptr_e; -+ u32 val; -+ -+ if (buffer->size == 0) -+ return; -+ -+ memset(tmp, 0, 128); -+ snd_info_get_str(tmp, buffer->buffer, 127); -+ -+ val = simple_strtoul(tmp, &ptr_e, 10); -+ if (*ptr_e == 'k') -+ val *= 1024; -+ else if (*ptr_e == 'm') -+ val *= 1024 * 1024; -+ -+ if (ac97) { -+ if (val > AC97_HW_BUFFER_BYTES_MAX) -+ val = AC97_HW_BUFFER_BYTES_MAX; -+ } else { -+ if (val > I2S_HW_BUFFER_BYTES_MAX) -+ val = I2S_HW_BUFFER_BYTES_MAX; -+ } -+ -+ snd_ftssp_pcm_hw.buffer_bytes_max = (size_t)val; -+} -+ -+static void snd_ftssp_period_min_read(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.period_bytes_min); -+} -+ -+static void snd_ftssp_period_min_write(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ char tmp[128]; -+ char *ptr_e; -+ u32 val; -+ -+ if (buffer->size == 0) -+ return; -+ -+ memset(tmp, 0, 128); -+ snd_info_get_str(tmp, buffer->buffer, 127); -+ -+ val = simple_strtoul(tmp, &ptr_e, 10); -+ if (*ptr_e == 'k') -+ val *= 1024; -+ else if (*ptr_e == 'm') -+ val *= 1024 * 1024; -+ -+ snd_ftssp_pcm_hw.period_bytes_min = (size_t)val; -+ -+ if ((val * snd_ftssp_pcm_hw.periods_max) > -+ snd_ftssp_pcm_hw.buffer_bytes_max) { -+ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " -+ "hw_buffer_size(%d).\n", -+ snd_ftssp_pcm_hw.period_bytes_min, -+ snd_ftssp_pcm_hw.periods_max, -+ snd_ftssp_pcm_hw.buffer_bytes_max); -+ INFO(" Unexpected access violation may occur!\n"); -+ } -+} -+ -+static void snd_ftssp_period_max_read(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.period_bytes_max); -+} -+ -+static void snd_ftssp_period_max_write(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ char tmp[128]; -+ char *ptr_e; -+ u32 val; -+ -+ if (buffer->size == 0) -+ return; -+ -+ memset(tmp, 0, 128); -+ snd_info_get_str(tmp, buffer->buffer, 127); -+ -+ val = simple_strtoul(tmp, &ptr_e, 10); -+ if (*ptr_e == 'k') -+ val *= 1024; -+ else if (*ptr_e == 'm') -+ val *= 1024 * 1024; -+ -+ snd_ftssp_pcm_hw.period_bytes_max = (size_t)val; -+ -+ if ((val * snd_ftssp_pcm_hw.periods_max) > -+ snd_ftssp_pcm_hw.buffer_bytes_max) { -+ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " -+ "hw_buffer_size(%d).\n", -+ snd_ftssp_pcm_hw.period_bytes_max, -+ snd_ftssp_pcm_hw.periods_max, -+ snd_ftssp_pcm_hw.buffer_bytes_max); -+ INFO(" Unexpected access violation may occur!\n"); -+ } -+} -+ -+static void snd_ftssp_periods_min_read(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.periods_min); -+} -+ -+static void snd_ftssp_periods_min_write(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ char tmp[128]; -+ char *ptr_e; -+ u32 val; -+ -+ if (buffer->size == 0) -+ return; -+ -+ memset(tmp, 0, 128); -+ snd_info_get_str(tmp, buffer->buffer, 127); -+ -+ val = simple_strtoul(tmp, &ptr_e, 10); -+ if (*ptr_e == 'k') -+ val *= 1024; -+ else if (*ptr_e == 'm') -+ val *= 1024 * 1024; -+ -+ snd_ftssp_pcm_hw.periods_min = (size_t)val; -+ -+ if ((val * snd_ftssp_pcm_hw.period_bytes_max) > -+ snd_ftssp_pcm_hw.buffer_bytes_max) { -+ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " -+ "hw_buffer_size(%d).\n", -+ snd_ftssp_pcm_hw.period_bytes_max, -+ snd_ftssp_pcm_hw.periods_min, -+ snd_ftssp_pcm_hw.buffer_bytes_max); -+ INFO(" Unexpected access violation may occur!\n"); -+ } -+} -+ -+static void snd_ftssp_periods_max_read(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ snd_iprintf(buffer, "%d\n", snd_ftssp_pcm_hw.periods_max); -+} -+ -+static void snd_ftssp_periods_max_write(struct snd_info_entry *entry, -+ struct snd_info_buffer *buffer) -+{ -+ char tmp[128]; -+ char *ptr_e; -+ u32 val; -+ -+ if (buffer->size == 0) -+ return; -+ -+ memset(tmp, 0, 128); -+ snd_info_get_str(tmp, buffer->buffer, 127); -+ -+ val = simple_strtoul(tmp, &ptr_e, 10); -+ if (*ptr_e == 'k') -+ val *= 1024; -+ else if (*ptr_e == 'm') -+ val *= 1024 * 1024; -+ -+ snd_ftssp_pcm_hw.periods_max = (size_t)val; -+ -+ if ((val * snd_ftssp_pcm_hw.period_bytes_max) > -+ snd_ftssp_pcm_hw.buffer_bytes_max) { -+ INFO("\nWarning: period_bytes(%d) * periods(%d) exceeds " -+ "hw_buffer_size(%d).\n", -+ snd_ftssp_pcm_hw.period_bytes_max, -+ snd_ftssp_pcm_hw.periods_max, -+ snd_ftssp_pcm_hw.buffer_bytes_max); -+ INFO(" Unexpected access violation may occur!\n"); -+ } -+} -+#endif //FTSSP_PROC_FS -+ -+static inline void ftssp_ac97_init(void) -+{ -+ //driver_name = AC97_DRIVER_NAME; -+ //codec_info = AC97_CODEC_NAME; -+ -+ /* Change codec-dependent callbacks to AC97 */ -+ ftssp010_substreams[0].pmu_set_clocking = pmu_set_ac97_clocking; -+ ftssp010_substreams[0].hw_config = ftssp010_config_ac97_play; -+ ftssp010_substreams[1].pmu_set_clocking = pmu_set_ac97_clocking; -+ ftssp010_substreams[1].hw_config = ftssp010_config_ac97_rec; -+ -+ snd_ftssp_playback_ops.copy = snd_ftssp_playback_copy; -+ snd_ftssp_capture_ops.copy = snd_ftssp_capture_copy; -+ -+ snd_ftssp_pcm_hw.rates = AC97_CODEC_SAMPLE_RATES; -+ snd_ftssp_pcm_hw.rate_min = AC97_CODEC_SAMPLE_RATE_MIN; -+ snd_ftssp_pcm_hw.rate_max = AC97_CODEC_SAMPLE_RATE_MAX; -+ snd_ftssp_pcm_hw.formats = AC97_CODEC_FORMATS; -+ snd_ftssp_pcm_hw.buffer_bytes_max = AC97_HW_BUFFER_BYTES_MAX; -+ snd_ftssp_pcm_hw.period_bytes_min = AC97_HW_PERIOD_BYTES_MIN; -+ snd_ftssp_pcm_hw.period_bytes_max = AC97_HW_PERIOD_BYTES_MAX; -+ snd_ftssp_pcm_hw.periods_min = AC97_HW_PERIODS_MIN; -+ snd_ftssp_pcm_hw.periods_max = AC97_HW_PERIODS_MAX; -+} -+ -+static int ftssp_alsa_init(struct i2c_client *client) -+{ -+ ftssp_chip *chip; -+ int err; -+ -+ //ADD by river 2011.03.08 -+ //g_i2c_client = client; -+ //End ADD by river 2011.03.08 -+ //printk(">>>>>>>>> (4) ftssp_alsa_init().\n"); -+ init_hw(cardno, ac97, client); -+ -+ if (ac97) -+ ftssp_ac97_init(); -+ -+ DBG("%s: FTSSP010 #%d (Physical Addr=0x%08X), mode: %s\n", -+ __func__, -+ cardno, SSP_FTSSP010_pa_base[cardno], -+ ac97 ? "ac97" : "i2s"); -+ -+ err = snd_card_create(cardno, FTSSP_CARD_ID, THIS_MODULE, -+ sizeof(ftssp_chip), &ftssp_cards[cardno]); -+ if (err < 0) -+ return err; -+ -+ if (ac97) { -+ sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME); -+ sprintf(ftssp_cards[cardno]->shortname, -+ FTSSP_DRIVER_NAME "_ac97"); -+ sprintf(ftssp_cards[cardno]->longname, -+ FTSSP_DRIVER_NAME "_ac97 controller"); -+ } else { -+ sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME); -+ sprintf(ftssp_cards[cardno]->shortname, -+ FTSSP_DRIVER_NAME "_i2s"); -+ sprintf(ftssp_cards[cardno]->longname, -+ FTSSP_DRIVER_NAME "_i2s controller"); -+ } -+ -+ // PCM -+ chip = (ftssp_chip *)(ftssp_cards[cardno]->private_data); -+ chip->card = ftssp_cards[cardno]; -+ -+ if ((err = snd_ftssp_new_pcm(chip))) { -+ ERR("%s, Can't new PCM devices\n",__func__); -+ return -ENODEV; -+ } -+ -+#if (FTSSP_PROC_FS) -+ // new a proc entries subordinate to card->proc_root for debugging -+ // /proc/card#/buf_max -+ snd_card_proc_new(chip->card, "buf_max", &chip->info_buf_max); -+ if (chip->info_buf_max) { -+ chip->info_buf_max->c.text.read = snd_ftssp_buf_max_read; -+ chip->info_buf_max->c.text.write = snd_ftssp_buf_max_write; -+ } -+ // /proc/card#/period_min -+ snd_card_proc_new(chip->card, "period_size_min", -+ &chip->info_period_min); -+ if (chip->info_period_min) { -+ chip->info_period_min->c.text.read = snd_ftssp_period_min_read; -+ chip->info_period_min->c.text.write = -+ snd_ftssp_period_min_write; -+ } -+ // /proc/card#/period_max -+ snd_card_proc_new(chip->card, "period_size_max", -+ &chip->info_period_max); -+ if (chip->info_period_max) { -+ chip->info_period_max->c.text.read = snd_ftssp_period_max_read; -+ chip->info_period_max->c.text.write = -+ snd_ftssp_period_max_write; -+ } -+ // /proc/card#/periods_min -+ snd_card_proc_new(chip->card, "periods_min", &chip->info_periods_min); -+ if (chip->info_periods_min) { -+ chip->info_periods_min->c.text.read = -+ snd_ftssp_periods_min_read; -+ chip->info_periods_min->c.text.write = -+ snd_ftssp_periods_min_write; -+ } -+ // /proc/card#/periods_max -+ snd_card_proc_new(chip->card, "periods_max", &chip->info_periods_max); -+ if (chip->info_periods_max) { -+ chip->info_periods_max->c.text.read = -+ snd_ftssp_periods_max_read; -+ chip->info_periods_max->c.text.write = -+ snd_ftssp_periods_max_write; -+ } -+#endif -+ -+ // Register the card to ALSA -+ if ((err = snd_card_register(chip->card)) == 0) { -+ INFO("%s card registered!\n", FTSSP_CARD_ID); -+ } -+ -+ return 0; -+} -+ -+#ifdef CONFIG_SND_FTSSP010_I2S -+//ADD by river 2011.01.26 -+static int alc5630_i2c_remove(struct i2c_client *client) -+{ -+ struct alc5630_data *alc5630 = i2c_get_clientdata(client); -+ -+ // power down codec chip -+ //tas_write_reg(tas, TAS_REG_ACR, 1, &tmp); -+ -+ mutex_destroy(&alc5630->mtx); -+ kfree(alc5630); -+ return 0; -+} -+ -+static const struct i2c_device_id alc5630_i2c_id[] = { -+ { "alc5630_codec", 0 }, -+ { } -+}; -+ -+// This is the driver that will be inserted -+static struct i2c_driver alc5630_driver = { -+ .driver = { -+ .name = "alc5630_codec", -+ .owner = THIS_MODULE, -+ }, -+ .attach_adapter = alc5630_i2c_attach, -+ .probe = alc5630_i2c_probe, -+ .remove = alc5630_i2c_remove, -+ .suspend = alc5630_i2c_suspend, -+ .resume = alc5630_i2c_resume, -+ .id_table = alc5630_i2c_id, -+}; -+ -+static int alc5630_i2c_suspend(struct i2c_client *i2c_client, pm_message_t mesg) -+{ -+ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() is invoked.\n"); -+ -+ //i2c_del_driver(&alc5630_driver); -+ //#ifndef CONFIG_SND_FTSSP010_AC97 -+ // i2c_del_driver(&alc5630_driver); -+ //#endif -+ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() -2 is invoked.\n"); -+ dmad_channel_free(&dma_chreq_tx); -+ dmad_channel_free(&dma_chreq_rx); -+ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_suspend() -3 is invoked.\n"); -+ //snd_card_free(ftssp_cards[cardno]); -+ -+ return 0; -+ -+} -+ -+static int alc5630_i2c_resume(struct i2c_client *i2c_client) -+{ -+ -+ //printk("@@@@@ TRACE by river 2011.05.10 : alc5630_i2c_resume() is invoked.\n"); -+ //#ifdef CONFIG_SND_FTSSP010_AC97 -+ // ftssp_alsa_init(NULL); -+ //#else -+ // return i2c_add_driver(&alc5630_driver); -+ //#endif -+ -+ return 0; -+ -+} -+#endif -+ -+static __init int ftssp_alsa_i2c_i2s_init(void) -+{ -+ -+ //printk(">>>>>>>>>> (1) ftssp_alsa_i2c_i2s_init().\n"); -+ //return i2c_add_driver(&alc5630_driver); -+ #ifdef CONFIG_SND_FTSSP010_AC97 -+ return ftssp_alsa_init(NULL); -+ #else -+ return i2c_add_driver(&alc5630_driver); -+ #endif -+} -+//End ADD by river 2011.01.26 -+ -+static __exit void ftssp_alsa_i2c_i2s_exit(void) -+{ -+ DBG("%s, cleaning up\n",__func__); -+ -+ //i2c_del_driver(&alc5630_driver); -+ #ifndef CONFIG_SND_FTSSP010_AC97 -+ i2c_del_driver(&alc5630_driver); -+ #endif -+ -+ dmad_channel_free(&dma_chreq_tx); -+ dmad_channel_free(&dma_chreq_rx); -+ -+ snd_card_free(ftssp_cards[cardno]); -+} -+ -+/*static __exit void ftssp_alsa_exit(void) -+{ -+ DBG("%s, cleaning up\n",__func__); -+ -+ dmad_channel_free(&dma_chreq_tx); -+ dmad_channel_free(&dma_chreq_rx); -+ -+ snd_card_free(ftssp_cards[cardno]); -+}*/ -+ -+//MOD by river 2011.01.26 -+//module_init(ftssp_alsa_init); -+//module_exit(ftssp_alsa_exit); -+module_init(ftssp_alsa_i2c_i2s_init); -+module_exit(ftssp_alsa_i2c_i2s_exit); -+//End MOD by river 2011.01.26 -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_HDA.c linux-3.4.113/sound/nds32/FTSSP010_HDA.c ---- linux-3.4.113.orig/sound/nds32/FTSSP010_HDA.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_HDA.c 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,745 @@ -+/* FTSSP010 - UDA1345TS module: -+ * -+ * $log$ -+ * -+ * 2006/02/23: I-Jui Sung: OSS emulation half-duplex -+ * playback/capture at 48K, 44.1K, 8K -+ * with mono/stereo 16bit/8bit -+ * -+ * 2006/02/22: I-Jui Sung: OSS emulation playback at 44.1KHz -+ * 16-bit mono completed. Relying ALSA to -+ * resample -+ * 2009/02/24: dma upgrade checking list: -+ * - ac97 mode playback ................. ok -+ * - ac97 mode capture .................. ok -+ * - i2s mode playback .................. ok -+ * - i2s mode capture ................... ok -+ * - mixer support (snd_ctl_add, ...) ... todo -+ * - debug /proc entry .................. ok -+ */ -+ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "FTSSP010_HDA.h" -+void init_hw(unsigned int cardno); -+ -+#if (!defined(CONFIG_PLATFORM_AHBDMA) && !defined(CONFIG_PLATFORM_APBDMA)) -+#warning needs ahb/apb dma to wrok -+#endif -+ -+/* --------------------------------------------------------------------------- -+ * Define the debug level of FTSSP_DEBUG -+ */ -+#define FTSSP_DEBUG 0 -+#define FTSSP_DEBUG_VERBOSE 0 -+#define FTSSP_PROC_FS 1 -+ -+#undef VVDBG -+#if (FTSSP_DEBUG_VERBOSE) -+//#define VVDBG(vvar...) (void)0 -+#define VVDBG(vvar...) printk(KERN_INFO vvar) -+#else -+#define VVDBG(vvar...) (void)0 -+#endif -+ -+#undef ERR -+#define ERR(vvar...) printk(KERN_ERR vvar) -+ -+#undef INFO -+#define INFO(vvar...) printk(KERN_INFO vvar) -+ -+#if (FTSSP_DEBUG) -+#undef DBG -+#define DBG(vvar...) printk(KERN_INFO vvar) -+#else -+#define DBG(vvar...) (void)0 -+#endif -+ -+#if (FTSSP_DEBUG_VERBOSE) -+#undef VDBG -+#define VDBG(vvar...) printk(KERN_INFO vvar) -+#else -+#define VDBG(vvar...) (void)0 -+#endif -+ -+/* --------------------------------------------------------------------------- -+ * Preserved size of memory space for audio DMA ring -+ */ -+#define FTSSP_HW_DMA_SIZE (512 * 1024) -+ -+ -+/* HDA HW configuration*/ -+/* ring size, exported to application */ -+#define HDA_HW_BUFFER_BYTES_MAX (256 * 1024) -+#define HDA_HW_PERIOD_BYTES_MIN (2 * 1024) -+#define HDA_HW_PERIOD_BYTES_MAX (32 * 1024) -+#define HDA_HW_PERIODS_MIN 3 -+#define HDA_HW_PERIODS_MAX 8 -+ -+#define HDA_HW_DMA_SIZE (HDA_HW_BUFFER_BYTES_MAX) -+ -+ -+/* --------------------------------------------------------------------------- -+ * Audio formats -+ */ -+ -+/* HDA formats */ -+#define HDA_CODEC_FORMATS (SNDRV_PCM_FMTBIT_S16_LE) -+#define HDA_CODEC_SAMPLE_RATES (SNDRV_PCM_RATE_192000 | \ -+ SNDRV_PCM_RATE_176400| \ -+ SNDRV_PCM_RATE_96000 | \ -+ SNDRV_PCM_RATE_88200 | \ -+ SNDRV_PCM_RATE_48000 | \ -+ SNDRV_PCM_RATE_44100 | \ -+ SNDRV_PCM_RATE_32000 | \ -+ SNDRV_PCM_RATE_22050 | \ -+ SNDRV_PCM_RATE_16000 | \ -+ SNDRV_PCM_RATE_11025 | \ -+ SNDRV_PCM_RATE_8000) -+#define HDA_CODEC_SAMPLE_RATE_MIN (8000) -+#define HDA_CODEC_SAMPLE_RATE_MAX (192000) -+ -+/* --------------------------------------------------------------------------- -+ * Configuration -+ */ -+#if (CONFIG_PROC_FS == 0) -+#undef FTSSP_PROC_FS -+#define FTSSP_PROC_FS 0 -+#else -+#if (FTSSP_PROC_FS) -+#include -+#endif /* FTSSP_PROC_FS */ -+#endif /* CONFIG_PROC_FS */ -+ -+#define FTSSP_CARD_ID "ftssp010" -+#define FTSSP_DRIVER_NAME "ftssp" -+ -+MODULE_LICENSE("Faraday License"); -+MODULE_AUTHOR("Faraday Technology Corp."); -+MODULE_DESCRIPTION("FTSSP010 Linux 2.6 Driver"); -+ -+static int cardno = 0; -+static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = -+ { SSP_FTSSP010_PA_BASE }; -+ -+/* Driver mode */ -+ -+// ---------------------------------------------- -+module_param(cardno, int, 0); -+MODULE_PARM_DESC(cardno, "FTSSP No."); -+ -+// ---------------------------------------------- -+ -+/* --------------------------------------------------------------------------- -+ * Structures -+ */ -+ -+/* private data for card */ -+typedef struct { -+ struct snd_card *card; -+ struct snd_pcm *pcm; -+ struct snd_pcm_substream *substream_tx; -+ struct snd_pcm_substream *substream_rx; -+} ftssp_chip; -+ -+/* dma request descriptors */ -+dmad_chreq dma_chreq_tx = { -+ .channel = -1, -+ .drq = NULL, -+}; -+ -+dmad_chreq dma_chreq_rx = { -+ .channel = -1, -+ .drq = NULL, -+}; -+ -+/* Holds ALSA card instance pointers */ -+struct snd_card *ftssp_cards[SSP_FTSSP010_COUNT]; -+ -+/* snd_pcm_hardware */ -+static struct snd_pcm_hardware snd_ftssp_pcm_hw = -+{ -+ .info = SNDRV_PCM_INFO_INTERLEAVED, -+ .formats = HDA_CODEC_FORMATS, -+ .rates = HDA_CODEC_SAMPLE_RATES, -+ .rate_min = HDA_CODEC_SAMPLE_RATE_MIN, -+ .rate_max = HDA_CODEC_SAMPLE_RATE_MAX, -+ .channels_min = 1, -+ .channels_max = 2, -+ .buffer_bytes_max = HDA_HW_BUFFER_BYTES_MAX, -+ .period_bytes_min = HDA_HW_PERIOD_BYTES_MIN, -+ .period_bytes_max = HDA_HW_PERIOD_BYTES_MAX, -+ .periods_min = HDA_HW_PERIODS_MIN, -+ .periods_max = HDA_HW_PERIODS_MAX, -+}; -+ -+/* private data for a substream (playback or capture) */ -+/* function pointer for set up AHBDMA for this substream */ -+typedef void (*start_t)(int cardno, unsigned use_dma); -+typedef void (*ftssp010_config_t)(int cardno, unsigned is_stereo, -+ unsigned speed, int use8bit); -+ -+typedef struct { -+ u32 busy; -+ spinlock_t dma_lock; -+ unsigned dma_area_va; -+ int dma_width; -+ unsigned int tx_period; -+ unsigned int rx_period; -+ -+ start_t start; -+ ftssp010_config_t hw_config; -+} ftssp_substream; -+ -+static ftssp_substream ftssp010_substreams[2] = { -+ /* Playback substream */ -+ { -+ busy : 0, -+ hw_config : ftssp010_config_hda_play, -+ }, -+ /* Capture substream */ -+ { -+ busy : 0, -+ hw_config : ftssp010_config_hda_rec, -+ } -+}; -+ -+ -+/** -+ * These dma callbacks are called in interrupt context. -+ * @data: pointer to the chip-wide structure. -+ * TODO: use stream-specifc data -+ */ -+__attribute__((__unused__)) -+static void ftssp_dma_callback_tx(int ch, u16 int_status, void *data) -+{ -+ ftssp_chip *chip = (ftssp_chip *)data; -+ struct snd_pcm_runtime *runtime = chip->substream_tx->runtime; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)runtime->private_data; -+ u32 sw_ptr; -+ u32 tx_period = ftssp010_substream->tx_period + 1; -+ -+ if (tx_period == runtime->periods) -+ sw_ptr = runtime->buffer_size; -+ else -+ sw_ptr = tx_period * runtime->period_size; -+ -+ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; -+ -+ if (dmad_update_ring_sw_ptr(&dma_chreq_tx, (u32)sw_ptr, 0)) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ } -+ -+ ftssp010_substream->tx_period = tx_period % runtime->periods; -+ snd_pcm_period_elapsed(chip->substream_tx); -+} -+ -+__attribute__((__unused__)) -+static void ftssp_dma_callback_rx(int ch, u16 int_status, void *data) -+{ -+ ftssp_chip *chip = (ftssp_chip *)data; -+ struct snd_pcm_runtime *runtime = chip->substream_rx->runtime; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)runtime->private_data; -+ u32 sw_ptr; -+ u32 rx_period = ftssp010_substream->rx_period + 1; -+ -+ if (rx_period == runtime->periods) -+ sw_ptr = runtime->buffer_size; -+ else -+ sw_ptr = rx_period * runtime->period_size; -+ sw_ptr = (u32)frames_to_bytes(runtime, sw_ptr) >> 1; -+ -+ if (dmad_update_ring_sw_ptr(&dma_chreq_rx, (u32)sw_ptr, 0) != 0) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ } -+ -+ ftssp010_substream->rx_period = rx_period % runtime->periods; -+ -+ snd_pcm_period_elapsed(chip->substream_rx); -+} -+ -+static inline int snd_ftssp_dma_ch_alloc(struct snd_pcm_substream *substream) -+{ -+ dmad_chreq *ch_req __attribute__((__unused__)) = 0; -+ -+#ifdef CONFIG_PLATFORM_APBDMA -+ -+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ch_req = &dma_chreq_tx; -+ ch_req->completion_cb = ftssp_dma_callback_tx; -+ ch_req->apb_req.tx_dir = DMAD_DIR_A0_TO_A1; -+ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97TX; -+ } else { -+ ch_req = &dma_chreq_rx; -+ ch_req->completion_cb = ftssp_dma_callback_rx; -+ ch_req->apb_req.tx_dir = DMAD_DIR_A1_TO_A0; -+ ch_req->apb_req.dev_reqn = APBBR_REQN_I2SAC97RX; -+ } -+ -+ ch_req->controller = DMAD_DMAC_APB_CORE; -+ ch_req->flags = DMAD_FLAGS_RING_MODE; -+ ch_req->ring_base = 0; -+ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); -+ ch_req->periods = 0; -+ ch_req->period_size = 0; -+ -+ ch_req->apb_req.ring_ctrl = APBBR_ADDRINC_I2X; -+ ch_req->apb_req.ring_reqn = APBBR_REQN_NONE; -+ ch_req->apb_req.dev_ctrl = APBBR_ADDRINC_FIXED; -+ ch_req->apb_req.burst_mode = 0; -+ ch_req->apb_req.data_width = APBBR_DATAWIDTH_2; -+ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); -+ -+ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ ERR("%s: APBDMA channel allocation failed\n",__func__); -+ goto _try_ahb; -+ } -+ -+ DBG("%s: APBDMA channel allocated (ch: %d) ring_mode\n", -+ __func__, ch_req->channel); -+ -+ return 0; -+ -+_try_ahb: -+ -+#endif /* CONFIG_PLATFORM_APBDMA */ -+ -+#ifdef CONFIG_PLATFORM_AHBDMA -+ -+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) { -+ ch_req = &dma_chreq_tx; -+ ch_req->completion_cb = ftssp_dma_callback_tx; -+ ch_req->ahb_req.tx_dir = DMAD_DIR_A0_TO_A1; -+ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97TX; -+ } else { -+ ch_req = &dma_chreq_rx; -+ ch_req->completion_cb = ftssp_dma_callback_rx; -+ ch_req->ahb_req.tx_dir = DMAD_DIR_A1_TO_A0; -+ ch_req->ahb_req.dev_reqn = DMAC_REQN_I2SAC97RX; -+ } -+ -+ ch_req->controller = DMAD_DMAC_AHB_CORE; -+ ch_req->flags = DMAD_FLAGS_RING_MODE; -+ ch_req->ring_base = 0; -+ ch_req->dev_addr = (dma_addr_t)FTSSP010_DATA_PA(cardno); -+ ch_req->periods = 0; -+ ch_req->period_size = 0; -+ -+ ch_req->ahb_req.sync = 1; -+ ch_req->ahb_req.priority = DMAC_CSR_CHPRI_2; -+ ch_req->ahb_req.hw_handshake = 1; -+ ch_req->ahb_req.burst_size = DMAC_CSR_SIZE_1; -+ -+ ch_req->ahb_req.ring_width = DMAC_CSR_WIDTH_32; -+ ch_req->ahb_req.ring_ctrl = DMAC_CSR_AD_INC; -+ ch_req->ahb_req.ring_reqn = DMAC_REQN_NONE; -+ ch_req->ahb_req.dev_width = DMAC_CSR_WIDTH_32; -+ ch_req->ahb_req.dev_ctrl = DMAC_CSR_AD_FIX; -+ -+ ch_req->completion_data = (void *)snd_pcm_substream_chip(substream); -+ -+ if (dmad_channel_alloc(ch_req) != 0) { -+ ERR("%s: AHBDMA channel allocation failed\n", __func__); -+ goto _err_exit; -+ } -+ -+ DBG("%s: AHBDMA channel allocated (ch: %d) ring_mode\n", -+ __func__, ch_req->channel); -+ -+ return 0; -+ -+_err_exit: -+ -+#endif /* CONFIG_PLATFORM_AHBDMA */ -+ -+ return -ENODEV; -+} -+ -+static inline ftssp_substream *ftssp010_substream_new(int stream_id) -+{ -+ ftssp_substream *s = NULL; -+ -+ switch (stream_id) { -+ case SNDRV_PCM_STREAM_PLAYBACK: -+ s = &ftssp010_substreams[0]; -+ break; -+ case SNDRV_PCM_STREAM_CAPTURE: -+ s = &ftssp010_substreams[1]; -+ break; -+ default: -+ ERR("%s: wrong stream type (%d)\n", __func__, stream_id); -+ return NULL; -+ } -+ -+ if (s->busy) { -+ ERR("%s: device busy!\n", __func__); -+ return NULL; -+ } -+ s->busy = 1; -+ -+ spin_lock_init(&s->dma_lock); -+ -+ return s; -+} -+ -+static int snd_ftssp_pcm_open(struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ int stream_id = substream->pstr->stream; -+ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ /* Both playback and capture share a hardware description */ -+ runtime->hw = snd_ftssp_pcm_hw; -+ -+ /* Allocate & Initialize stream-specific data */ -+ runtime->private_data = ftssp010_substream_new(stream_id); -+ -+ if (runtime->private_data) -+ return snd_ftssp_dma_ch_alloc(substream); -+ else -+ return -EBUSY; -+} -+ -+static int snd_ftssp_pcm_close(struct snd_pcm_substream *substream) -+{ -+ int stream_id = substream->pstr->stream; -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)substream->runtime->private_data; -+ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) -+ dmad_channel_free(&dma_chreq_tx); -+ else -+ dmad_channel_free(&dma_chreq_rx); -+ -+ ftssp010_substream->busy = 0; -+ return 0; -+} -+ -+static int snd_ftssp_pcm_hw_params(struct snd_pcm_substream *substream, -+ struct snd_pcm_hw_params *hw_params) -+{ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ return snd_pcm_lib_malloc_pages(substream, HDA_HW_DMA_SIZE); -+} -+ -+static int snd_ftssp_pcm_hw_free(struct snd_pcm_substream *substream) -+{ -+ VDBG("%s, %s\n", __func__, -+ (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) ? -+ "playback" : "capture"); -+ -+ if (substream->pstr->stream == SNDRV_PCM_STREAM_PLAYBACK) -+ dmad_drain_requests(&dma_chreq_tx, 1); -+ else -+ dmad_drain_requests(&dma_chreq_rx, 1); -+ -+ return snd_pcm_lib_free_pages(substream); -+} -+ -+/* Prepare FTSSP010 AHBDMA for playback & capture */ -+static int snd_ftssp_pcm_prepare(struct snd_pcm_substream *substream) -+{ -+ ftssp_chip *chip = snd_pcm_substream_chip(substream); -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)runtime->private_data; -+ -+ int stream_id = substream->pstr->stream; -+ dmad_chreq *dma_chreq; -+ unsigned period_size, buffer_size; -+ VVDBG("%s before spin_lock<<\n", __func__); -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) -+ dma_chreq = &dma_chreq_tx; -+ else -+ dma_chreq = &dma_chreq_rx; -+ -+ period_size = frames_to_bytes(runtime, runtime->period_size); -+ buffer_size = frames_to_bytes(runtime, runtime->buffer_size); -+ -+ if (runtime->format != SNDRV_PCM_FORMAT_S16_LE) -+ return -ENODEV; -+ -+ ftssp010_substream->dma_width = 4; -+ -+ dmad_drain_requests(dma_chreq, 1); -+ -+ dma_chreq->ring_base = (dma_addr_t)runtime->dma_addr; -+ dma_chreq->periods = (dma_addr_t)runtime->periods; -+ dma_chreq->period_size = (dma_addr_t)(period_size >> 1); -+ dma_chreq->ring_size = (dma_addr_t)(buffer_size >> 1); -+ dmad_update_ring(dma_chreq); -+ -+ /* Set PMU, FTSSP010, and DMA */ -+ spin_lock(&ftssp010_substream->dma_lock); -+ -+ /* keep DMA buffer VA for copy() callback */ -+ // todo: support playback/capture simultaneously -+ ftssp010_substream->dma_area_va = (u32)runtime->dma_area; -+ VVDBG("%s before hw_config<<\n", __func__); -+ ftssp010_substream->hw_config(cardno, -+ runtime->channels > 1 ? 1 : 0, /* 1: stereo, 0: mono */ -+ runtime->rate, ftssp010_substream->dma_width); -+ VVDBG("%s after hw_config<<\n", __func__); -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ ftssp010_substream->tx_period = 0; -+ chip->substream_tx = substream; -+ } else { -+ ftssp010_substream->rx_period = 0; -+ chip->substream_rx = substream; -+ } -+ -+ spin_unlock(&ftssp010_substream->dma_lock); -+ VVDBG("%s after spin_unlock <<\n", __func__); -+ -+ return 0; -+} -+ -+static inline int snd_ftssp_start_play(ftssp_substream *ftssp010_substream, -+ struct snd_pcm_runtime *runtime) -+{ -+ int err = 0; -+ u32 sw_ptr = -+ (u32)frames_to_bytes(runtime, runtime->buffer_size) >> 1; -+ -+ err = dmad_update_ring_sw_ptr(&dma_chreq_tx, sw_ptr, 0); -+ if (err != 0) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ return err; -+ } -+ err = dmad_kickoff_requests(&dma_chreq_tx); -+ if (err != 0) { -+ ERR("%s: failed to kickoff dma!\n", __func__); -+ return err; -+ } -+ -+ return 0; -+} -+ -+static inline int snd_ftssp_start_record(ftssp_substream *ftssp010_substream, -+ struct snd_pcm_runtime *runtime) -+{ -+ int err = 0; -+ u32 sw_ptr = (u32)frames_to_bytes(runtime, runtime->buffer_size); -+ -+ sw_ptr = sw_ptr >> 1; -+ printk(">>>>>>>>>> : snd_ftssp_start_record() for recording....\n"); -+ err = dmad_update_ring_sw_ptr(&dma_chreq_rx, sw_ptr, 0); -+ if (err != 0) { -+ ERR("%s: failed to update sw-pointer!\n", __func__); -+ return err; -+ } -+ -+ err = dmad_kickoff_requests(&dma_chreq_rx); -+ if (err != 0) { -+ ERR("%s: failed to kickoff dma!\n", __func__); -+ return err; -+ } -+ -+ -+ return 0; -+} -+ -+/* Triggers AHBDMA for playback & capture */ -+static int snd_ftssp_pcm_trigger(struct snd_pcm_substream * substream, int cmd) -+{ -+ ftssp_substream *ftssp010_substream = -+ (ftssp_substream *)substream->runtime->private_data; -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ int err = 0; -+ int stream_id = substream->pstr->stream; -+ -+ /* note local interrupts are already disabled in the midlevel code */ -+ spin_lock(&ftssp010_substream->dma_lock); -+ -+ switch (cmd) { -+ case SNDRV_PCM_TRIGGER_START: -+ -+ VDBG("%s: SNDRV_PCM_TRIGGER_START state(0x%08x)\n", -+ __func__, (u32)runtime->status->state); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ err = snd_ftssp_start_play(ftssp010_substream, runtime); -+ } else { -+ err = snd_ftssp_start_record(ftssp010_substream, -+ runtime); -+ } -+ break; -+ -+ case SNDRV_PCM_TRIGGER_STOP: -+ -+ VDBG("%s: SNDRV_PCM_TRIGGER_STOP state(0x%08x)\n", -+ __func__, (u32)substream->runtime->status->state); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ ftssp010_stop_tx(cardno); -+ dmad_drain_requests(&dma_chreq_tx, 1); -+ } else { -+ ftssp010_stop_rx(cardno); -+ dmad_drain_requests(&dma_chreq_rx, 1); -+ } -+ break; -+ default: -+ err = -EINVAL; -+ break; -+ } -+ -+ spin_unlock(&ftssp010_substream->dma_lock); -+ return err; -+} -+ -+// pcm middle-layer call this function within irq (snd_pcm_period_elapsed) or -+// with local irq disabled (snd_pcm_lib_write1) -+static snd_pcm_uframes_t snd_ftssp_pcm_pointer( -+ struct snd_pcm_substream *substream) -+{ -+ struct snd_pcm_runtime *runtime = substream->runtime; -+ u32 hw_ptr; -+ snd_pcm_uframes_t ret; -+ int stream_id = substream->pstr->stream; -+ -+ /* Fetch DMA pointer, with spin lock */ -+ //spin_lock_irqsave(&ftssp010_substream->dma_lock, flags); -+ -+ if (stream_id == SNDRV_PCM_STREAM_PLAYBACK) { -+ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_tx); -+ } else { -+ hw_ptr = dmad_probe_ring_hw_ptr(&dma_chreq_rx); -+ } -+ ret = bytes_to_frames(runtime, hw_ptr << 1); -+ //spin_unlock_irqrestore(&ftssp010_substream->dma_lock, flags); -+ VVDBG("%s: hw_ptr(0x%08x) ret(0x%08x)\n", -+ (stream_id == SNDRV_PCM_STREAM_PLAYBACK) ? "p" : "c", -+ (u32)hw_ptr, (u32)ret); -+ -+ /* ALSA requires return value 0 <= ret < buffer_size */ -+ if (ret >= runtime->buffer_size) -+ return 0; -+ return ret; -+} -+ -+/* For FTSSP010 driver, operations are shared among playback & capture */ -+static struct snd_pcm_ops snd_ftssp_playback_ops = { -+ .open = snd_ftssp_pcm_open, -+ .close = snd_ftssp_pcm_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_ftssp_pcm_hw_params, -+ .hw_free = snd_ftssp_pcm_hw_free, -+ .prepare = snd_ftssp_pcm_prepare, -+ .trigger = snd_ftssp_pcm_trigger, -+ .pointer = snd_ftssp_pcm_pointer, -+ .copy = NULL, -+}; -+ -+static struct snd_pcm_ops snd_ftssp_capture_ops = { -+ .open = snd_ftssp_pcm_open, -+ .close = snd_ftssp_pcm_close, -+ .ioctl = snd_pcm_lib_ioctl, -+ .hw_params = snd_ftssp_pcm_hw_params, -+ .hw_free = snd_ftssp_pcm_hw_free, -+ .prepare = snd_ftssp_pcm_prepare, -+ .trigger = snd_ftssp_pcm_trigger, -+ .pointer = snd_ftssp_pcm_pointer, -+ .copy = NULL, -+}; -+ -+/* ALSA PCM constructor */ -+static int snd_ftssp_new_pcm(ftssp_chip *chip) -+{ -+ struct snd_pcm *pcm; -+ int err; -+ -+ /* PCM device #0 with 1 playback and 1 capture */ -+ if ((err = snd_pcm_new(chip->card, "ftssp_pcm", 0, 1, 1, &pcm)) < 0) -+ return err; -+ -+ pcm->private_data = chip; -+ strcpy(pcm->name, "ftssp_pcm device"); -+ chip->pcm = pcm; -+ -+ /* set operators for playback and capture*/ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_PLAYBACK, -+ &snd_ftssp_playback_ops); -+ -+ snd_pcm_set_ops(pcm, SNDRV_PCM_STREAM_CAPTURE, -+ &snd_ftssp_capture_ops); -+ -+ /* Pre-allocate buffer, as suggested by ALSA driver document */ -+ // todo: support playback/capture simultaneously -+ snd_pcm_lib_preallocate_pages_for_all(pcm, SNDRV_DMA_TYPE_DEV, -+ NULL, FTSSP_HW_DMA_SIZE, FTSSP_HW_DMA_SIZE); -+ -+ return 0; -+} -+ -+static __init int ftssp_alsa_init(void) -+{ -+ ftssp_chip *chip; -+ int err; -+ init_hw(cardno); -+ INFO("After init_hw!\n"); -+ err = snd_card_create(cardno, FTSSP_CARD_ID, THIS_MODULE, -+ sizeof(ftssp_chip), &ftssp_cards[cardno]); -+ INFO("After snd_card_create!\n"); -+ if (err < 0) -+ return err; -+ sprintf(ftssp_cards[cardno]->driver, FTSSP_DRIVER_NAME); -+ sprintf(ftssp_cards[cardno]->shortname, -+ FTSSP_DRIVER_NAME "_HDA"); -+ sprintf(ftssp_cards[cardno]->longname, -+ FTSSP_DRIVER_NAME "_HDA controller"); -+ /* PCM */ -+ chip = (ftssp_chip *)(ftssp_cards[cardno]->private_data); -+ chip->card = ftssp_cards[cardno]; -+ -+ if ((err = snd_ftssp_new_pcm(chip))) { -+ ERR("%s, Can't new PCM devices\n",__func__); -+ return -ENODEV; -+ } -+ -+ -+ /* Register the card to ALSA */ -+ if ((err = snd_card_register(chip->card)) == 0) { -+ INFO("%s card registered!\n", FTSSP_CARD_ID); -+ } -+ -+ return 0; -+} -+ -+static __exit void ftssp_alsa_exit(void) -+{ -+ DBG("%s, cleaning up\n",__func__); -+ -+ dmad_channel_free(&dma_chreq_tx); -+ dmad_channel_free(&dma_chreq_rx); -+ -+ snd_card_free(ftssp_cards[cardno]); -+} -+ -+module_init(ftssp_alsa_init); -+module_exit(ftssp_alsa_exit); -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_HDA.h linux-3.4.113/sound/nds32/FTSSP010_HDA.h ---- linux-3.4.113.orig/sound/nds32/FTSSP010_HDA.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_HDA.h 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,34 @@ -+/* FTSSP010 - HDA supporting library header */ -+/* -+ * -+ * $log$ -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+ -+#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) -+#define FTSSP010_DATA_PA(x) (SSP_FTSSP010_pa_base[(x)]+0x18) -+ -+ -+/* Returns FTSSP010 status */ -+extern void ftssp010_set_int_control(int cardno, unsigned val); -+extern int ftssp010_get_status(int cardno); -+extern unsigned ftssp010_get_int_status(int cardno); -+/* Polls FIFO full register */ -+extern int ftssp010_tx_fifo_not_full(int cardno); -+ -+/* Configure FTSSP010 to a given sampling rate and channel number */ -+extern void ftssp010_config_hda_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit); -+ -+extern void ftssp010_config_hda_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit); -+ -+extern void ftssp010_stop_tx(int cardno); -+extern void ftssp010_stop_rx(int cardno); -+ -+ -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_HDA_lib.c linux-3.4.113/sound/nds32/FTSSP010_HDA_lib.c ---- linux-3.4.113.orig/sound/nds32/FTSSP010_HDA_lib.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_HDA_lib.c 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,477 @@ -+/* FTSSP010 - UDA1345TS module -+ * -+ * $log$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "hda.h" -+ -+#if 0 -+MODULE_LICENSE("Faraday License"); -+MODULE_AUTHOR("Faraday Technology Corp."); -+MODULE_DESCRIPTION("FTSSP010 - UDA1345TS Linux 2.6 Library"); -+#endif -+#undef ERR -+#define ERR(vvar...) printk(KERN_ERR vvar) -+#define DBG(vvar...) printk(KERN_INFO vvar) -+ -+#define SSP_TXFCLR 0x8 -+#define SSP_RXFCLR 0x4 -+#define SSP_RFIEN 0x4 -+#define SSP_TFIEN 0x8 -+#define SSP_SSPEN 0x1 -+#define SSP_TXDOE 0x2 -+#define SSP_RXDMAEN 0x10 -+#define SSP_TXDMAEN 0x20 -+#define SSP_RFURIEN 0x1 -+#define SSP_TFURIEN 0x2 -+#define HDA_STRNUM_RX 1 -+#define HDA_STRNUM_TX 2 -+#define HDA_CHANUM 0 -+#define HDA_CRST_MASK 0x20 -+/* Initialize FTSSP010 to output to UDA1345TS via I2S */ -+#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0) -+#define FTSSP010_CONTROL0_OPM_STEREO 0xC -+#define FTSSP010_CONTROL0_OPM_MONO 0x8 -+ -+#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4) -+#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8) -+ -+#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10) -+#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC) -+#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14) -+#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) -+#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C) -+#define FTSSP010_AC_COMMAND(x) (SSP_FTSSP010_va_base[(x)]+0x28) -+#define FTSSP010_IRSPR(x) (SSP_FTSSP010_va_base[(x)]+0x2C) -+#define FTSSP010_ICMDST(x) (SSP_FTSSP010_va_base[(x)]+0x30) -+#define HDA_REG_OSDC(x) (SSP_FTSSP010_va_base[(x)]+0x50) -+#define HDA_REG_ISDC(x) (SSP_FTSSP010_va_base[(x)]+0x54) -+ -+static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE }; -+static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE }; -+ -+void SetSSP_Enable(int cardno, int enable) -+{ -+ volatile unsigned int ctrl = 0; -+ -+ ctrl = inl(FTSSP010_CONTROL2(cardno)); -+ if(enable) -+ ctrl |= SSP_SSPEN + SSP_TXDOE; -+ else -+ ctrl &= ~(SSP_SSPEN + SSP_TXDOE); -+ -+ outl(ctrl, FTSSP010_CONTROL2(cardno)); -+} -+void SetSSP_Enable_rx(int cardno, int enable) -+{ -+ volatile unsigned int ctrl = 0; -+ -+ ctrl = inl(FTSSP010_CONTROL2(cardno)); -+ if(enable) -+ ctrl |= SSP_SSPEN ; -+ else -+ ctrl &= ~(SSP_SSPEN); -+ -+ outl(ctrl, FTSSP010_CONTROL2(cardno)); -+} -+ -+void SetSSP_FIFO_Threshold(int cardno, unsigned int trans_len,unsigned int rec_len) -+{ -+ volatile unsigned int ctrl = 0; -+ ctrl = inl(FTSSP010_INT_CONTROL(cardno)); -+ -+ ctrl &= ~0x0000FF00; -+ ctrl |= ((trans_len << 12) + (rec_len << 8)) & 0x0000FF00; -+ -+ outl(ctrl, FTSSP010_INT_CONTROL(cardno)); -+} -+void SetSSP_IntMask(int cardno,int Mask) -+{ -+ volatile unsigned int ctrl = 0; -+ ctrl = inl(FTSSP010_INT_CONTROL(cardno)); -+ ctrl &= ~0x3F; -+ ctrl |= Mask; -+ outw(ctrl, FTSSP010_INT_CONTROL(cardno)); -+} -+void SetSSP_TXFIFO(int cardno, unsigned int threshold,unsigned int underrun) -+{ -+ volatile unsigned int data = 0; -+ -+ data = inl(FTSSP010_INT_CONTROL(cardno)); -+ -+ if (threshold) -+ data |= SSP_TFIEN; -+ else -+ data &= ~SSP_TFIEN; //Howard@2007-4-13 -+ -+ if (underrun) -+ data |= SSP_TFURIEN; -+ else -+ data &= ~SSP_TFURIEN; //Howard@2007-4-13 -+ -+ outl(data, FTSSP010_INT_CONTROL(cardno)); -+} -+void SetSSP_RXFIFO(int cardno,unsigned int threshold,unsigned int underrun) -+{ -+ volatile unsigned int data = 0; -+ -+ data = inl(FTSSP010_INT_CONTROL(cardno)); -+ -+ if (threshold) -+ data |= SSP_RFIEN; -+ else -+ data &= ~SSP_RFIEN; //Howard@2007-4-13 -+ -+ if (underrun) -+ data |= SSP_RFURIEN; -+ else -+ data &= ~SSP_RFURIEN; //Howard@2007-4-13 -+ -+ outl(data, FTSSP010_INT_CONTROL(cardno)); -+} -+void SetSSP_DMA(int cardno, unsigned int trans,unsigned int rec) -+{ -+ volatile unsigned int data = 0; -+ -+ data = inl(FTSSP010_INT_CONTROL(cardno)); -+ -+ if (trans) -+ data |= SSP_TXDMAEN; -+ else -+ data &= ~SSP_TXDMAEN; -+ -+ if (rec) -+ data |= SSP_RXDMAEN; -+ else -+ data &= ~SSP_RXDMAEN; -+ -+ outl(data, FTSSP010_INT_CONTROL(cardno)); -+} -+void SSPClearTxFIFO(int cardno) -+{ -+ volatile unsigned int data = 0; -+ -+ data = inl(FTSSP010_CONTROL2(cardno)); -+ data |= SSP_TXFCLR; -+ outl(data, FTSSP010_CONTROL2(cardno)); -+} -+ -+ -+void SSPClearRxFIFO(int cardno) -+{ -+ volatile unsigned int data = 0; -+ -+ data = inl(FTSSP010_CONTROL2(cardno)); -+ data |= SSP_RXFCLR; -+ outl(data, FTSSP010_CONTROL2(cardno)); -+} -+ -+void ftssp010_set_int_control(int cardno, unsigned val) -+{ -+ outl(val, FTSSP010_INT_CONTROL(cardno)); -+} -+ -+unsigned ftssp010_get_int_status(int cardno) -+{ -+ return (inl(FTSSP010_INT_STATUS(cardno))); -+} -+ -+int ftssp010_get_status(int cardno) -+{ -+ return (inl(FTSSP010_STATUS(cardno))); -+} -+ -+int ftssp010_tx_fifo_not_full(int cardno) -+{ -+ return (inl(FTSSP010_STATUS(cardno))&0x2)==0x2; -+} -+ -+int ftssp010_tx_fifo_vaild_entries(int cardno) -+{ -+ return (inl(FTSSP010_STATUS(cardno))>>12) & 0x1f; -+} -+ -+/* Configure FTSSP010 to a given sampling rate and channel number -+ * for HDA mode in playback mode -+ */ -+void init_hw(unsigned int cardno) -+{ -+ /* Step 1: Set HDA Mode & HDA Format */ -+ outl(HDA_MODE | 0x4000, FTSSP010_CONTROL0(cardno)); /* set FTSSP010 to HDA mode */ -+ mdelay(50); -+ outl(HDA_CRST_CLR | (5 << HDA_RST_FCNT_OFS), FTSSP010_CONTROL2(cardno)); /* Cold Reset AC-Link */ -+ mdelay(50); -+ while((inl(FTSSP010_CONTROL2(cardno)) & HDA_CRST_MASK) != HDA_CRST_CLR); -+ SetSSP_IntMask(cardno, 0); -+ -+} -+void SSPClearFIFO(int cardno, unsigned int tx, unsigned int rx) -+{ -+ unsigned int data; -+ -+ if (tx == 1) { -+ //clear TX -+ data = inl(FTSSP010_CONTROL2(cardno)); -+ //data = REG32(SSP_REG_CTRL2); -+ data |= SSP_TXFCLR; -+ outl(data, FTSSP010_CONTROL2(cardno)); -+ //REG32(SSP_REG_CTRL2) = data; -+ } -+ -+ if (rx == 1) { -+ //clear RX -+ data = inl(FTSSP010_CONTROL2(cardno)); -+ //data = REG32(SSP_REG_CTRL2); -+ data |= SSP_RXFCLR; -+ //REG32(SSP_REG_CTRL2) = data; -+ outl(data, FTSSP010_CONTROL2(cardno)); -+ } -+} -+void hda_cmd_rsp(int cardno, unsigned int node_num, unsigned int verb_num, unsigned int func_num) -+{ -+ //unsigned int HDA_REG_ICMDST; -+ volatile unsigned int hda_cmd = HDA_COD_DEVADDR | (node_num << 20) | (verb_num << 8) | func_num; -+ //Wait CMD Bus Not Busy -+ while((inl(FTSSP010_ICMDST(cardno)) & HDA_ICB_MASK) != 0); -+ //Write CMD into ICW -+ outl(hda_cmd, FTSSP010_AC_COMMAND(cardno)); -+ mdelay(50); -+ //Wait new resp is latched into IRR -+ while((inl(FTSSP010_ICMDST(cardno)) & HDA_IRV_MASK) == 0); -+ //Get Resp From IRR & Compare with Expected Resp -+ //clear IRV -+ outl(inl(FTSSP010_ICMDST(cardno)) | (1 << HDA_IRV_OFFSET), FTSSP010_ICMDST(cardno)); -+ mdelay(50); -+} -+void hda_cmdrsp_proc(int cardno, unsigned int node_num, unsigned int issue_cmd, unsigned int expect_rsp) -+{ -+ unsigned int hda_cmd = HDA_COD_DEVADDR | node_num | issue_cmd; -+ unsigned int HDA_REG_ICMDST; -+ //Wait CMD Bus Not Busy -+ while((inl(FTSSP010_ICMDST(cardno)) & HDA_ICB_MASK) != 0); -+ -+ //Write CMD into ICW -+ //REG32(HDA_REG_ICMDW) = hda_cmd; -+ outl(hda_cmd, FTSSP010_AC_COMMAND(cardno)); -+ mdelay(50); -+ //Wait new resp is latched into IRR -+ while((inl(FTSSP010_ICMDST(cardno)) & HDA_IRV_MASK) == 0); -+ //Get Resp From IRR & Compare with Expected Resp -+ if (inl(FTSSP010_IRSPR(cardno)) != expect_rsp) { -+ ERR("%s: unexpected rsp!",__func__); -+ } -+ else { -+ //clear IRV -+ outl(inl(FTSSP010_ICMDST(cardno)) | (1 << HDA_IRV_OFFSET), FTSSP010_ICMDST(cardno)); -+ } -+} -+unsigned int hda_covfmt_setup(unsigned int type, unsigned int base, unsigned int mult, unsigned int div, unsigned int bits, unsigned int chnum) -+{ -+ unsigned int hda_fmt = type << HDA_FMT_TYPE_OFS | -+ base << HDA_FMT_BASE_OFS | -+ mult << HDA_FMT_MULT_OFS | -+ div << HDA_FMT_DIV_OFS | -+ bits << HDA_FMT_BITS_OFS | -+ chnum << HDA_FMT_CHNUM_OFS; -+ return hda_fmt; -+} -+unsigned int hda_covstr_setup(unsigned int stream, unsigned int channel) -+{ -+ unsigned int hda_str = stream << HDA_STR_STR_OFS | -+ channel << HDA_STR_CHA_OFS ; -+ return hda_str; -+} -+unsigned int hda_converter_setup(int cardno, unsigned int mode, unsigned int type, unsigned int base, unsigned mult, unsigned int div, unsigned int bits, unsigned int chnum, unsigned int stream, unsigned int channel) -+{ -+ unsigned int hda_fmt = 0; -+ unsigned int hda_str = 0; -+ unsigned int exp_rsp = 0; -+ unsigned int node_num = 0; -+ -+ if (mode == HDA_OUT_STR) { -+ node_num = HDA_OUTCOV_NODE; -+ } -+ else { -+ node_num = HDA_INCOV_NODE; -+ } -+ //a: Set Converter Format to Converter -+ hda_fmt = hda_covfmt_setup(type, base, mult, div, bits, chnum); -+ exp_rsp = HDA_RESP_ZERO_VAL; -+ hda_cmdrsp_proc(cardno, node_num, (HDA_CMD_SETCVTFMT | hda_fmt), exp_rsp); -+ //b: Get Converter Format from Converter -+ exp_rsp = hda_fmt; -+ hda_cmdrsp_proc(cardno, node_num, HDA_CMD_GETCVTFMT, exp_rsp); -+ //c: Set Converter Stream to Converter -+ hda_str = hda_covstr_setup(stream, channel); -+ exp_rsp = HDA_RESP_ZERO_VAL; -+ hda_cmdrsp_proc(cardno, node_num, (HDA_CMD_SETCVTSTR | hda_str), exp_rsp); -+ //d: Get Converter Stream from Converter -+ exp_rsp = hda_str; -+ hda_cmdrsp_proc(cardno, node_num, HDA_CMD_GETCVTSTR, exp_rsp); -+ -+ return hda_fmt; -+} -+void hda_iosdc_setup(int cardno, unsigned int io_sel, unsigned int ctrl, unsigned int stream_num, unsigned int hda_fmt) -+{ -+ unsigned int hda_reg_base = (io_sel == 1)? HDA_REG_OSDC(cardno) : HDA_REG_ISDC(cardno); -+ if (ctrl == 1) {//run -+ outl((stream_num << HDA_SDC_STNUM_OFFSET) | hda_fmt, hda_reg_base); -+ outl((inl(hda_reg_base) | (1 << HDA_SDC_SRUN_OFFSET)),hda_reg_base); -+ } -+ -+} -+static void _ftssp010_config_hda(int cardno, unsigned is_stereo, unsigned speed, int is_rec) -+{ -+ unsigned int hda_fmt = 0; -+ unsigned int div = 0,mult = 0, base = 0; -+ switch (speed) { -+ case 44100: -+ base = 1; -+ div = 0; -+ break; -+ case 48000: -+ div = 0; -+ break; -+ case 96000: -+ mult = 1; -+ break; -+ case 192000: -+ mult = 3; -+ break; -+ } -+ -+ if (is_rec) { /* Recording */ -+ /* ------------------------------------------------ */ -+ /* Codec initialization */ -+ /* ------------------------------------------------ */ -+ /* Step 3: Codec Evaluation */ -+ /* root_node -> node 1(Audio Func Group) */ -+ /* -> node 2(Output Converter) */ -+ /* -> node 3(Input Converter) */ -+ /* ------------------------------------------------ */ -+ //input -+ hda_cmd_rsp(cardno, 0x1a, 0x707, 0x20); //pin complex => input enable, port-c LINE1 -+ hda_cmd_rsp(cardno, 0x08, 0x3f0, 0x3f);//pin amp => max LINE ADC amplifier gain -+ hda_cmd_rsp(cardno, 0x1a, 0x3f0, 0x00);//pin complex => no mute -+ hda_cmd_rsp(cardno, 0x23, 0x3f2, 0x3f);//pin complex => no mute -+ /* ------------------------------ */ -+ /* Step 4: Output Converter Setup */ -+ /* ------------------------------ */ -+ /* Set Converter Format & Stream to Node 2(Output Converter) */ -+ /* type = PCM, base = 48K, mult = xN, div = /M, bits = 8~32bits/sample, chnum = 1 */ -+ /* stream = 1, lowest channel = 0 */ -+ -+ hda_fmt = hda_converter_setup(cardno, HDA_IN_STR, //MODE -+ 0, base, mult, div, 1, 1, //FORMAT -+ HDA_STRNUM_RX, HDA_CHANUM); //STREAM -+ /* ---------------------------- */ -+ /* Step 5: Enable Output Stream */ -+ /* ---------------------------- */ -+ hda_iosdc_setup(cardno, HDA_IN_STR, HDA_STR_RUN, HDA_STRNUM_RX, hda_fmt); -+ SetSSP_Enable_rx(cardno, 1); -+ SetSSP_RXFIFO(cardno, 0, 0); -+ SetSSP_TXFIFO(cardno, 0, 0); -+ SetSSP_FIFO_Threshold(cardno,12,12); -+ SetSSP_DMA(cardno, 0, 1); -+ -+ SSPClearTxFIFO(cardno); -+ SSPClearRxFIFO(cardno); -+ -+ //SetSSP_Enable_rx(cardno, 0); -+ -+ } else { /* Playback */ -+ /* ------------------------------------------------ */ -+ /* Codec initialization */ -+ /* ------------------------------------------------ */ -+ /* Step 3: Codec Evaluation */ -+ /* root_node -> node 1(Audio Func Group) */ -+ /* -> node 2(Output Converter) */ -+ /* -> node 3(Input Converter) */ -+ /* ------------------------------------------------ */ -+ //DBG("%s before_cmd_rsp<<",__func__); -+ hda_cmd_rsp(cardno, 0x14, 0x707, 0x40);//pin complex => output -+ //DBG("%s after hda_cmd_rsp< output>>",__func__); -+ hda_cmd_rsp(cardno, 0x0c, 0x3f0, 0x3f);//pin amp => 0x3f -+ hda_cmd_rsp(cardno, 0x14, 0x3f0, 0x00);//pin complex => no mute -+ //DBG("%s after hda_cmd_rsp",__func__); -+ //msleep_interruptible(10); -+ /* ------------------------------ */ -+ /* Step 4: Output Converter Setup */ -+ /* ------------------------------ */ -+ /* Set Converter Format & Stream to Node 2(Output Converter) */ -+ /* type = PCM, base = 48K, mult = xN, div = /M, bits = 8~32bits/sample, chnum = 1 */ -+ /* stream = 1, lowest channel = 0 */ -+ hda_fmt = hda_converter_setup(cardno, HDA_OUT_STR, //MODE -+ 0, base, mult, div, 1, 1, //FORMAT -+ HDA_STRNUM_TX, HDA_CHANUM); //STREAM -+ //DBG("%s after hda_converter_setup",__func__); -+ /* ---------------------------- */ -+ /* Step 5: Enable Output Stream */ -+ /* ---------------------------- */ -+ hda_iosdc_setup(cardno, HDA_OUT_STR, HDA_STR_RUN, HDA_STRNUM_TX, hda_fmt); -+ SetSSP_Enable(cardno, 1); -+ SetSSP_RXFIFO(cardno, 0, 0); -+ SetSSP_TXFIFO(cardno, 0, 0); -+ //outl(0xC, FTSSP010_CONTROL2(cardno)); /* Disable FTSSP010, clear RX/TX Fifo. */ -+ SetSSP_FIFO_Threshold(cardno,12,12); -+ SetSSP_DMA(cardno,1,0); -+ -+ SSPClearTxFIFO(cardno); -+ SSPClearRxFIFO(cardno); -+ } -+ -+ while(inl(FTSSP010_INT_STATUS(cardno))&0x3); -+} -+/* for HDA */ -+void ftssp010_config_hda_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit) -+{ -+ _ftssp010_config_hda(cardno, is_stereo, speed, 0); -+} -+ -+void ftssp010_config_hda_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit) -+{ -+ _ftssp010_config_hda(cardno, is_stereo, speed, 1); -+} -+ -+ -+ -+void ftssp010_stop_tx(int cardno) -+{ -+ unsigned int hda_reg_base = HDA_REG_OSDC(cardno); -+ SetSSP_Enable(cardno,0); -+ SetSSP_DMA(cardno,0,0); -+ -+ /* turn off output node */ -+ hda_cmd_rsp(cardno,0x14, 0x707, 0); //pin complex => input enable, port-c LINE1 -+ hda_cmd_rsp(cardno,0x0c, 0x3f0, 0x80); //pin amp => max LINE ADC amplifier gain -+ hda_cmd_rsp(cardno,0x14, 0x3f0, 0x80); //pin complex => no mute -+ -+ outl(0, hda_reg_base); -+ SSPClearFIFO(cardno, 1, 0); -+ //outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x22), FTSSP010_INT_CONTROL(cardno)); -+} -+ -+void ftssp010_stop_rx(int cardno) -+{ -+ unsigned int hda_reg_base = HDA_REG_ISDC(cardno); -+ SetSSP_Enable_rx(cardno, 0); -+ SetSSP_DMA(cardno, 0, 0); -+ -+ /* turn off output node */ -+ hda_cmd_rsp(cardno,0x1a, 0x707, 0); //pin complex => input enable, port-c LINE1 -+ hda_cmd_rsp(cardno,0x08, 0x3f0, 0x80);//pin amp => LINE ADC amplifier gain -+ hda_cmd_rsp(cardno,0x1a, 0x3f0, 0x80);//pin complex => mute -+ hda_cmd_rsp(cardno,0x23, 0x3f2, 0x80);//pin complex => no mute -+ -+ outl(0, hda_reg_base); -+ SSPClearFIFO(cardno, 0, 1); -+ //outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x11), FTSSP010_INT_CONTROL(cardno)); -+} -+ -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_lib.c linux-3.4.113/sound/nds32/FTSSP010_lib.c ---- linux-3.4.113.orig/sound/nds32/FTSSP010_lib.c 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_lib.c 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,795 @@ -+/* FTSSP010 - UDA1345TS module -+ * -+ * $log$ -+ */ -+ -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include -+#include "FTSSP010_UDA1345TS.h" -+ -+#if 0 -+MODULE_LICENSE("Faraday License"); -+MODULE_AUTHOR("Faraday Technology Corp."); -+MODULE_DESCRIPTION("FTSSP010 - UDA1345TS Linux 2.6 Library"); -+#endif -+ -+#define PMU_PDLLCR1 (PMU_FTPMU010_VA_BASE+0x34) -+#define PMU_MFPSR (PMU_FTPMU010_VA_BASE+0x28) -+#define PMU_I2SAC97_REQACKCFG (PMU_FTPMU010_VA_BASE+0xbc) -+#define PMU_C4 (PMU_FTPMU010_VA_BASE+0xc4) -+ -+#define SSPCLK_TO_SCLKDIV(sspclk_div2,bps) ((sspclk_div2)/(bps)-1) -+ -+// Each client has this additional data -+struct alc5630_data { -+ struct i2c_client *client; -+ struct delayed_work work; -+ unsigned long gpio2_value; -+ struct mutex mtx; -+}; -+ -+//ADD by river 2011.01.26 -+static int i2s_alc5630_read(unsigned int raddr, char *data, struct i2c_client *client) -+{ -+#ifndef CONFIG_SND_FTSSP010_AC97 -+ struct i2c_adapter *adap = client->adapter; -+ int ret; -+#endif -+ struct i2c_msg msg; -+ int i2c_value; -+ -+ //Reading ALC5630 register -+ msg.addr = raddr; -+ msg.flags = (client->flags & I2C_M_TEN) | I2C_M_RD; -+ msg.len = 1; -+ msg.buf = (char *)data; -+ -+ //ret = i2c_transfer(adap, &msg, 1); -+#ifndef CONFIG_SND_FTSSP010_AC97 -+ ret = i2c_transfer(adap, &msg, 1); -+ if (ret != 0) { -+ printk("i2c read failed\n"); -+ return -1; -+ } -+ else -+#endif -+ { -+ i2c_value = (data[0]&0xff) << 8 | (data[1]&0xff); -+ return i2c_value; -+ } -+} -+ -+static void i2s_alc5630_write(unsigned int raddr, unsigned int data, struct i2c_client *client) -+{ -+#ifndef CONFIG_SND_FTSSP010_AC97 -+ struct i2c_adapter *adap = client->adapter; -+ int ret; -+#endif -+ struct i2c_msg msg; -+ char buf[3]; -+ -+ //Writing ALC5630 register -+ msg.addr = raddr; -+ msg.flags = (client->flags & I2C_M_TEN) | ~I2C_M_RD; -+ msg.len = 1; -+ -+ buf[0] = (data >> 8) & 0xff; -+ buf[1] = data & 0xff; -+ msg.buf = (char *)buf; -+ -+ //ret = i2c_transfer(adap, &msg, 1); -+#ifndef CONFIG_SND_FTSSP010_AC97 -+ ret = i2c_transfer(adap, &msg, 1); -+ if (ret != 0) -+ { -+ printk("i2c write failed\n"); -+ } -+#endif -+} -+ -+/* -+static void i2s_alc5630_master_stereo_mode(struct i2c_client *client) -+{ -+ //printk(">>>>>>>>> (7) i2s_alc5630_master_stereo_mode() is called.\n"); -+ i2s_alc5630_write(0x02, 0x5f5f, client); -+ mdelay(50); -+ i2s_alc5630_write(0x04, 0x5f5f, client); -+ mdelay(50); -+ i2s_alc5630_write(0x26, 0x000f, client); -+ mdelay(50); -+ i2s_alc5630_write(0x34, 0x0000, client); // codec master mode -+ //i2s_alc5630_write(0x34, 0x8000, client); // codec slave mode -+ mdelay(50); -+ i2s_alc5630_write(0x3a, 0x0801, client); -+ mdelay(50); -+ i2s_alc5630_write(0x3c, 0xffff, client); -+ mdelay(50); -+ i2s_alc5630_write(0x3e, 0xffff, client); -+ mdelay(50); -+ i2s_alc5630_write(0x60, 0x3075, client); // codec master mode. divider. -+ mdelay(50); -+ i2s_alc5630_write(0x62, 0x1010, client); // codec master mode. divider. -+ -+} -+*/ -+ -+/* -+static void i2s_alc5630_read_test(struct i2c_client *client) -+{ -+ char data[3]; -+ printk(">>>>> : i2s_alc5630_read_test().....\n"); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0, i2s_alc5630_read(0x0, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x02, i2s_alc5630_read(0x02, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x04, i2s_alc5630_read(0x04, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x06, i2s_alc5630_read(0x06, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x08, i2s_alc5630_read(0x08, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0a, i2s_alc5630_read(0x0a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0c, i2s_alc5630_read(0x0c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x0e, i2s_alc5630_read(0x0e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x10, i2s_alc5630_read(0x10, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x12, i2s_alc5630_read(0x12, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x14, i2s_alc5630_read(0x14, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x16, i2s_alc5630_read(0x16, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x18, i2s_alc5630_read(0x18, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x1a, i2s_alc5630_read(0x1a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x1c, i2s_alc5630_read(0x1c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x1e, i2s_alc5630_read(0x1e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x20, i2s_alc5630_read(0x20, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x22, i2s_alc5630_read(0x22, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x24, i2s_alc5630_read(0x24, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x26, i2s_alc5630_read(0x26, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x28, i2s_alc5630_read(0x28, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x2a, i2s_alc5630_read(0x2a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x2c, i2s_alc5630_read(0x2c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x2e, i2s_alc5630_read(0x2e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x30, i2s_alc5630_read(0x30, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x32, i2s_alc5630_read(0x32, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x34, i2s_alc5630_read(0x34, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x36, i2s_alc5630_read(0x36, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x38, i2s_alc5630_read(0x38, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x3a, i2s_alc5630_read(0x3a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x3c, i2s_alc5630_read(0x3c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x3e, i2s_alc5630_read(0x3e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x40, i2s_alc5630_read(0x40, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x42, i2s_alc5630_read(0x42, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x44, i2s_alc5630_read(0x44, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x46, i2s_alc5630_read(0x46, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x48, i2s_alc5630_read(0x48, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x4a, i2s_alc5630_read(0x4a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x4c, i2s_alc5630_read(0x4c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x4e, i2s_alc5630_read(0x4e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x50, i2s_alc5630_read(0x50, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x52, i2s_alc5630_read(0x52, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x54, i2s_alc5630_read(0x54, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x56, i2s_alc5630_read(0x56, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x58, i2s_alc5630_read(0x58, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x5a, i2s_alc5630_read(0x5a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x5c, i2s_alc5630_read(0x5c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x5e, i2s_alc5630_read(0x5e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x60, i2s_alc5630_read(0x60, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x62, i2s_alc5630_read(0x62, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x64, i2s_alc5630_read(0x64, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x66, i2s_alc5630_read(0x66, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x68, i2s_alc5630_read(0x68, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x6a, i2s_alc5630_read(0x6a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x6c, i2s_alc5630_read(0x6c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x6e, i2s_alc5630_read(0x6e, data,client)); -+ -+ printk("Reg 0x%02x = 0x%08x\n", 0x70, i2s_alc5630_read(0x70, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x72, i2s_alc5630_read(0x72, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x74, i2s_alc5630_read(0x74, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x76, i2s_alc5630_read(0x76, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x78, i2s_alc5630_read(0x78, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x7a, i2s_alc5630_read(0x7a, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x7c, i2s_alc5630_read(0x7c, data,client)); -+ printk("Reg 0x%02x = 0x%08x\n", 0x7e, i2s_alc5630_read(0x7e, data,client)); -+ -+} -+*/ -+ -+static void i2s_al5630_slave_stereo_mode(struct i2c_client *client) -+{ -+ -+ -+ i2s_alc5630_write(0x34, 0x8000, client); // codec slave mode -+ i2s_alc5630_write(0x0c, 0x1010, client); -+ i2s_alc5630_write(0x10, 0xee03, client); -+ i2s_alc5630_write(0x1c, 0x0748, client); -+ //i2s_alc5630_write(0x02, 0x8080, client); -+ //i2s_alc5630_write(0x04, 0x8888, client); -+ i2s_alc5630_write(0x62, 0x0000, client); -+ -+} -+ -+//End ADD by river 2011.01.26 -+ -+ -+/* Drive PMU to generate I2S main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ -+void pmu_set_i2s_clocking(unsigned int speed) -+{ -+ unsigned int pmu_pdllcr1; /* PLL/DLL Control Register 1 */ -+ /* Configure PMU to generate I2S main clock */ -+ #ifdef CONFIG_PLAT_AG101 -+ pmu_pdllcr1 = inl(PMU_PDLLCR1)&0xfff0ffff; /* Bit 19-16 are relevent */ -+ #endif -+ -+ switch (speed) { -+ case 8000: -+ pmu_pdllcr1 |= 0x00000000; /* 2.048MHz x2 */ -+ break; -+ case 11025: -+ pmu_pdllcr1 |= 0x00010000; /* 2.8224MHz x2 */ -+ break; -+ case 16000: -+ pmu_pdllcr1 |= 0x00020000; /* 4.096MHz x2 */ -+ break; -+ case 22050: -+ pmu_pdllcr1 |= 0x00030000; /* 5.6448MHz x2 */ -+ break; -+ case 32000: -+ pmu_pdllcr1 |= 0x00040000; /* 8.192MHz x2 */ -+ break; -+ case 44100: -+ pmu_pdllcr1 |= 0x00050000; /* 11.2896Mhz x2 */ -+ break; -+ case 48000: -+ pmu_pdllcr1 |= 0x00060000; /* 12.2880MHz x2 */ -+ break; -+ default: -+ printk("%s: Unknown i2s speed %d\n",__func__,speed); -+ }; -+ -+ #ifdef CONFIG_PLAT_AG101 -+ outl(pmu_pdllcr1, PMU_PDLLCR1); -+ /* Configure PMU to select I2S output (instead of AC97) */ -+ outl(inl(PMU_MFPSR)&(~(1<<3)), PMU_MFPSR); /* clear bit 3 of MFPSR*/ -+ #endif -+} -+ -+/* Drive PMU to generate AC97 main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ -+void pmu_set_ac97_clocking(unsigned int speed) -+{ -+ /* Configure PMU to select AC97 output (instead of I2S) */ -+ /* Set GPIO[26] to AC97 clock, use 49.152MHz main clock (AC97 CLK1) */ -+ //outl(inl(PMU_MFPSR)|((1<<13)|(1<<3)), PMU_MFPSR); /* Set bit 13 & 3 of MFPSR*/ -+ #ifndef CONFIG_PLAT_AG102 -+ outl(inl(PMU_MFPSR)|((1<<13)|(1<<3)), PMU_MFPSR); /* Set bit 13 & 3 of MFPSR*/ -+ #endif -+} -+ -+/* Programs PMU to set I2S/AC97 DMA Channel, ch=0-7 */ -+void pmu_set_i2s_dma_channel(unsigned ch) -+{ -+ #ifdef CONFIG_PLAT_AG101 -+ ch&=0x7; -+ //outl((inl(PMU_I2SAC97_REQACKCFG)&(~0x7))|ch, PMU_I2SAC97_REQACKCFG); -+ outl(0xa, PMU_I2SAC97_REQACKCFG); -+ outl(0xb, PMU_C4); -+ #endif -+} -+ -+/* Initialize FTSSP010 to output to UDA1345TS via I2S */ -+#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0) -+#define FTSSP010_CONTROL0_OPM_STEREO 0xC -+#define FTSSP010_CONTROL0_OPM_MONO 0x8 -+ -+#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4) -+#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8) -+ -+#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10) -+#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC) -+#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14) -+#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) -+#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C) -+ -+//static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE }; -+//static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE }; -+ -+//ADD by river 2011.02.11 -+static struct i2c_client *g_i2c_client; -+ -+ -+#define FTSSP010_ACLINK_SLOT_VALID(x) (SSP_FTSSP010_va_base[(x)]+0x20) -+ -+void ftssp010_set_int_control(int cardno, unsigned val) -+{ -+ outl(val, FTSSP010_INT_CONTROL(cardno)); -+} -+ -+unsigned ftssp010_get_int_status(int cardno) -+{ -+ return (inl(FTSSP010_INT_STATUS(cardno))); -+} -+ -+int ftssp010_get_status(int cardno) -+{ -+ return (inl(FTSSP010_STATUS(cardno))); -+} -+ -+int ftssp010_tx_fifo_not_full(int cardno) -+{ -+ return (inl(FTSSP010_STATUS(cardno))&0x2)==0x2; -+} -+ -+int ftssp010_tx_fifo_vaild_entries(int cardno) -+{ -+ return (inl(FTSSP010_STATUS(cardno))>>12) & 0x1f; -+} -+ -+#include "FTSSP010_W83972D.h" -+ -+// AC97 codec tags -+#define TAG_COMMAND 0xe000 -+#define TAG_DATA 0x9800 /* Slot 3/4 */ -+#define TAG_DATA_MONO 0x9000 /* Slot 3 */ -+//#define TAG_DATA_LINE_IN 0x9000 /* Slot 3 */ -+ -+void ftssp010_ac97_write_codec_start(unsigned int cardno) -+{ -+ outl(0x0, FTSSP010_INT_CONTROL(cardno));/*Disable interrupts & DMA req */ -+ outl(0xC, FTSSP010_CONTROL2(cardno)); /* Disable FTSSP010, clear RX/TX Fifo. */ -+ outl(TAG_COMMAND, FTSSP010_ACLINK_SLOT_VALID(cardno)); -+} -+ -+void ftssp010_ac97_write_codec(unsigned int cardno,unsigned int reg,unsigned int data) -+{ -+ outl(reg << 12, FTSSP010_DATA(cardno)); -+ mdelay(50); -+ outl(data << 4, FTSSP010_DATA(cardno)); -+ mdelay(50); -+} -+ -+void ftssp010_ac97_write_codec_commit(unsigned int cardno) -+{ -+ while((inl(FTSSP010_CONTROL2(cardno))&0x1)==0) { -+ outl(0x3 , FTSSP010_CONTROL2(cardno)); /* SSPEN + TXDOE */ -+ } -+ while(ftssp010_tx_fifo_vaild_entries(cardno)) -+ ; -+ /* Wait for frame completion */ -+ while((inl(FTSSP010_INT_STATUS(cardno))&0x10)==0) -+ ; -+ outl(0x0, FTSSP010_CONTROL2(cardno)); -+} -+ -+/* Configure FTSSP010 to a given sampling rate and channel number -+ * for AC97 mode in playback mode -+ */ -+void init_hw(unsigned int cardno,unsigned int ac97, struct i2c_client *client) -+{ -+ -+ //printk(">>>>>>>>>> (5) init_hw() is called.\n"); -+ g_i2c_client = client; -+ -+ if(ac97) -+ { -+ //pmu_set_ac97_clocking(48000); -+ #ifndef CONFIG_PLAT_AG102 -+ pmu_set_ac97_clocking(48000); -+ #endif -+ outl(0x400c, FTSSP010_CONTROL0(cardno)); /* set FTSSP010 to AC97 mode */ -+ mdelay(50); -+ outl(0xc400, FTSSP010_INT_CONTROL(cardno)); -+ mdelay(50); -+ outl(0x20, FTSSP010_CONTROL2(cardno)); /* Cold Reset AC-Link */ -+ mdelay(50); -+ while(inl(FTSSP010_CONTROL2(cardno))) -+ mdelay(50); -+ outl(0x40, FTSSP010_CONTROL2(cardno)); /* Reset AC-Link */ -+ mdelay(1500); -+ } -+ else -+ { -+ -+ //printk(">>>>>>>>> (6) I2S mode selected....YAYAYA......\n"); -+ #ifdef CONFIG_PLAT_AG101 -+ outl(inl(PMU_MFPSR)&(~(1<<3)), PMU_MFPSR); /* clear bit 3 of MFPSR*/ -+ outl(0xa, PMU_I2SAC97_REQACKCFG); -+ outl(0xb, PMU_C4); -+ #endif -+ -+ //MOD by river 2011.01.26 -+ //i2s_alc5630_master_stereo_mode(client); -+ i2s_al5630_slave_stereo_mode(client); -+ //ssp_slave_stereo_mode(); -+ //End MOD by river 2011.01.26 -+ outl(0x311c, FTSSP010_CONTROL0(cardno)); /* I2S Master */ -+ outl(0, FTSSP010_CONTROL1(cardno)); /* I2S Master */ -+ outl(0xc400, FTSSP010_INT_CONTROL(cardno)); /* I2S Master */ -+ outl(0x40, FTSSP010_CONTROL2(cardno)); /* Reset AC-Link */ -+ -+ //i2s_alc5630_read_test(client); -+ } -+} -+static void _ftssp010_config_ac97(int cardno, unsigned is_stereo, unsigned speed, int is_rec) -+{ -+ /* Codec initialization */ -+ ftssp010_ac97_write_codec_start(cardno); -+ ftssp010_ac97_write_codec(cardno, W83972D_RESET, 0); -+ ftssp010_ac97_write_codec_commit(cardno); -+ -+ msleep_interruptible(10); -+ ftssp010_ac97_write_codec_start(cardno); -+ -+ if (is_rec) { /* Recording */ -+ /* Mute output */ -+ //ftssp010_ac97_write_codec(cardno, W83972D_STEREO_OUTPUT_CONTROL, 0x8000); -+ /* Mute PCM */ -+ //ftssp010_ac97_write_codec(cardno, W83972D_PCM_OUTPUT_CONTROL, 0x8000); -+ -+ /* Register 0x10, Line-In/Mic Gain */ -+ ftssp010_ac97_write_codec(cardno, W83972D_LINE_IN_VOLUME, 0x808); -+ //ftssp010_ac97_write_codec(cardno, W83972D_AUX_INPUT_CONTROL, 0x808); -+ ftssp010_ac97_write_codec(cardno, W83972D_MIC_VOLUME, 0x8); -+ /* FIXME: REC from line-in only */ -+ -+ /* Register 0x1A, Record Select=StereoMix */ -+ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_SELECT, 0x505 /*404*/); -+ /* Register 0x1C, Record Gain=0db */ -+ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN, 0x808); -+ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN_MIC, 0x8); -+ } else { /* Playback */ -+ /* Register 0x10, Mute Line-In/Mic Gain */ -+ ftssp010_ac97_write_codec(cardno, W83972D_LINE_IN_VOLUME, 0x8000); -+ ftssp010_ac97_write_codec(cardno, W83972D_MIC_VOLUME, 0x8000); -+ -+ /* Register 0x1A, Mute Record Gains */ -+ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN, 0x8000); -+ ftssp010_ac97_write_codec(cardno, W83972D_RECORD_GAIN_MIC, 0x8000); -+ -+ /* Output */ -+ ftssp010_ac97_write_codec(cardno, W83972D_STEREO_OUTPUT_CONTROL, 0); -+ ftssp010_ac97_write_codec(cardno, W83972D_PCM_OUTPUT_CONTROL, 0x808); -+ } -+ -+#if 0 -+ ftssp010_ac97_write_codec(cardno, W83972D_EXT_AUDIO_CONTROL, 0x1); -+ ftssp010_ac97_write_codec(cardno, W83972D_DAC_SAMPLE_RATE_CONTROL, speed); -+#endif -+ -+ ftssp010_ac97_write_codec_commit(cardno); -+ msleep_interruptible(10); -+ -+ /* Start data transfer */ -+// if(is_rec) { -+// outl(TAG_DATA_LINE_IN, FTSSP010_ACLINK_SLOT_VALID(cardno)); -+// } else { -+ if(is_stereo) -+ outl(TAG_DATA, FTSSP010_ACLINK_SLOT_VALID(cardno)); -+ else -+ outl(TAG_DATA_MONO, FTSSP010_ACLINK_SLOT_VALID(cardno)); -+// } -+ while(inl(FTSSP010_INT_STATUS(cardno))&0x3); -+// msleep_interruptible(10); -+} -+ -+void ftssp010_config_ac97_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit) -+{ -+ _ftssp010_config_ac97(cardno, is_stereo, speed, 0); -+} -+ -+void ftssp010_config_ac97_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit) -+{ -+ _ftssp010_config_ac97(cardno, is_stereo, speed, 1); -+} -+/* -+ * Configure FTSSP010 to a given sampling rate and channel number -+ * for I2S mode -+ */ -+void ftssp010_config(int cardno, unsigned is_stereo, unsigned speed, int width, int is_rec) -+{ -+ int use8bit = (width == 1 ? 1 : 0); -+ unsigned opm, bps = 2 * (use8bit ? 8 : 16); /* bits per 1 second audio data. */ -+ unsigned fpclkdiv = 0; -+ -+ //ADD by river 2011.06.02 -+ struct alc5630_data *alc5630; -+ char data[3]; -+ opm = is_stereo ? FTSSP010_CONTROL0_OPM_STEREO : FTSSP010_CONTROL0_OPM_MONO; -+ //MOD by river 2011.01.27 -+ outl(0x3100 | opm, FTSSP010_CONTROL0(cardno)); /* I2S Master */ -+ //End MOD by river 2011.01.27 -+ -+#if 0 -+ printk("%s: use %dHz %d-bit %s \n",__func__, -+ speed, -+ use8bit?8:16, -+ is_stereo?"stereo":"mono" -+ ); -+#endif -+ -+ /* configures CONTROL1 to use suitable clock divider. -+ the I2S clock is generated from PMU. */ -+ bps *= speed; -+ switch(speed) { -+ case 8000: /* SCLK : 256KHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //? -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ //i2s_alc5630_write(0x44, 0x6a0, g_i2c_client); //? -+ //i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ //i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0xBB; -+ -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(2048000, bps); -+ break; -+ case 11025: /* SCLK : 352.8KHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //? -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0x88; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(2822400, bps); -+ break; -+ case 16000: /* SCLK : 512KHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); //? -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0x5f; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(4096000, bps); -+ break; -+ case 22050: /* SCLK : 705.6KHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0x45; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(5644800, bps); -+ break; -+ case 24000: /* SCLK : 768KHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0x3e; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(5644800, bps); -+ break; -+ case 32000: /* SCLK : 1024KHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ //fpclkdiv = 0x2e; -+ fpclkdiv = 0x2f; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(8192000, bps); -+ break; -+ case 44100: /* SCLK : 1.4112 MHZ */ /* 96 MHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0x22; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(11289600, bps); -+ break; -+ case 48000: /* SCLK : 1.536 MHZ */ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); -+ i2s_alc5630_write(0x60, 0x3174, g_i2c_client); -+ i2s_alc5630_write(0x62, 0x1010, g_i2c_client); -+ fpclkdiv = 0x1f; -+ //fpclkdiv=SSPCLK_TO_SCLKDIV(12288000, bps); -+ -+ break; -+ default: -+ printk("%s: unsupported speed %d\n", __func__,speed); -+ return; -+ }; -+ -+ -+ if(!use8bit) { -+ outl(0xf0000|fpclkdiv, FTSSP010_CONTROL1(cardno)); /* 16bits */ -+ //outl(0xf0000|0x10, FTSSP010_CONTROL1(cardno)); /* 16bits */ -+ //outl(0xf0000|0x22, FTSSP010_CONTROL1(cardno)); /* 16bits */ -+ } else { -+ outl(0x70000|fpclkdiv, FTSSP010_CONTROL1(cardno)); /* 8bits */ -+ } -+ -+ //printk("#####$$$$$ : bps = %d\n", bps); -+ //printk("#####$$$$$ : speed = %d\n", speed); -+ //printk("#####$$$$$ : fpclkdiv = 0x%08x\n", fpclkdiv); -+ //printk("#####$$$$$ : FTSSP010_CONTROL1(cardno) = 0x%08x\n", inl(FTSSP010_CONTROL1(cardno))); -+ -+ if(is_rec) -+ outl(inl(FTSSP010_INT_CONTROL(cardno))&(~0x0f15), FTSSP010_INT_CONTROL(cardno)); /* Disable all interrupts */ -+ else -+ outl(inl(FTSSP010_INT_CONTROL(cardno))&(~0xf02a) , FTSSP010_INT_CONTROL(cardno)); /* Disable all interrupts */ -+ -+ outl(0xc, FTSSP010_CONTROL2(cardno)); /* clear FIFOs */ -+ -+ //ADD by river 2011.06.02 -+ alc5630 = i2c_get_clientdata(g_i2c_client); -+ //End -+ -+ if(is_rec) { -+ printk("ftssp010_config() for I2S mode in record.\n"); -+ //ADD by river 2011.03.21 -+ //TEST by river 2011.03.22 for recording => workable -+ //i2s_alc5630_write(0x0e, 0x8888, g_i2c_client); -+ i2s_alc5630_write(0x0e, 0x0808, g_i2c_client); -+ i2s_alc5630_write(0x10, 0xee03, g_i2c_client); -+ i2s_alc5630_write(0x22, 0x0500, g_i2c_client); -+ i2s_alc5630_write(0x1c, 0x0748, g_i2c_client); -+ i2s_alc5630_write(0x14, 0x1f1f, g_i2c_client); -+ i2s_alc5630_write(0x12, 0xdfdf, g_i2c_client); -+ -+ i2s_alc5630_write(0x26, 0x000f, g_i2c_client); -+ i2s_alc5630_write(0x3a, 0xffff, g_i2c_client); -+ i2s_alc5630_write(0x3c, 0xffff, g_i2c_client); -+ //i2s_alc5630_write(0x3e, 0xffff, g_i2c_client); -+ i2s_alc5630_write(0x3e, 0x80cf, g_i2c_client); -+ -+ i2s_alc5630_write(0x44, 0x3ea0, g_i2c_client); -+ i2s_alc5630_write(0x42, 0x2000, g_i2c_client); -+ i2s_alc5630_write(0x40, 0x8c0a, g_i2c_client); -+ -+ //i2s_alc5630_write(0x02, 0x0000, g_i2c_client); -+ i2s_alc5630_write(0x02, 0x8080, g_i2c_client); -+ i2s_alc5630_write(0x04, 0x0000, g_i2c_client); -+ //End TEST by river 2011.03.22 -+ -+ //printk("ftssp010_config() for I2S mode (Recording) ===> Dump register.\n"); -+ //i2s_alc5630_read_test(g_i2c_client); -+ -+ } -+ else { -+ //printk("ftssp010_config() for I2S mode in playback.\n"); -+ //ADD by river 2011.03.24 for record and playback case -+ i2s_alc5630_write(0x0e, 0x0808, g_i2c_client); -+ i2s_alc5630_write(0x12, 0xcbcb, g_i2c_client); -+ i2s_alc5630_write(0x14, 0x7f7f, g_i2c_client); -+ i2s_alc5630_write(0x22, 0x0000, g_i2c_client); -+ i2s_alc5630_write(0x3e, 0x8000, g_i2c_client); -+ i2s_alc5630_write(0x40, 0x0c0a, g_i2c_client); -+ i2s_alc5630_write(0x42, 0x0000, g_i2c_client); -+ //End ADD by river 2011.03.24 for record and playback case -+ -+ //TEST by river 2011.03.23 -+ i2s_alc5630_write(0x26, 0x0000, g_i2c_client); -+ i2s_alc5630_write(0x3c, 0x2000, g_i2c_client); -+ i2s_alc5630_write(0x3a, 0x0002, g_i2c_client); -+ i2s_alc5630_write(0x3c, 0xa330, g_i2c_client); -+ i2s_alc5630_write(0x3a, 0xc843, g_i2c_client); -+ //End TEST by river 2011.03.23 -+ -+ //ADD by river 2011.03.23 for HP Out De-pop -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0002 , g_i2c_client); -+ i2s_alc5630_write(0x04, i2s_alc5630_read(0x04, data,g_i2c_client)|0x8080 , g_i2c_client); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0040 , g_i2c_client); -+ i2s_alc5630_write(0x3c, i2s_alc5630_read(0x3C, data,g_i2c_client)|0x2000 , g_i2c_client); -+ i2s_alc5630_write(0x3E, i2s_alc5630_read(0x3E, data,g_i2c_client)|0xfC00 , g_i2c_client); -+ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x0100 , g_i2c_client); -+ mdelay(500); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0200 , g_i2c_client); -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0100 , g_i2c_client); -+ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)& 0xfeff ,g_i2c_client); -+ //End ADD by river 2011.03.23 for HP Out De-pop -+ -+ -+ //TEST by river 2011.03.22 -+ i2s_alc5630_write(0x1c, 0x0748, g_i2c_client); -+ //End TEST by river 2011.03.22 -+ -+ -+ //TEST by river 2011.03.16 -+ //i2s_alc5630_write(0x02, 0x8080, g_i2c_client); -+ i2s_alc5630_write(0x26, 0x000f, g_i2c_client); -+ //End TEST by river 2011.03.16 -+ -+ //ADD by river 2011.03.23 -+ if (alc5630->gpio2_value==0x0) -+ i2s_alc5630_write(0x3A, (i2s_alc5630_read(0x3A, data,g_i2c_client) & 0xFBFF)|0x0040 , g_i2c_client); -+ else -+ i2s_alc5630_write(0x3A, i2s_alc5630_read(0x3A, data,g_i2c_client)|0x0440 , g_i2c_client); -+ -+ -+ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x0020 , g_i2c_client); -+ i2s_alc5630_write(0x5E, i2s_alc5630_read(0x5E, data,g_i2c_client)|0x00c0 , g_i2c_client); -+ i2s_alc5630_write(0x04, i2s_alc5630_read(0x04, data,g_i2c_client)& 0x7f7f , g_i2c_client); -+ mdelay(30); -+ -+ if (alc5630->gpio2_value==0x0) { -+ //printk(">>>>>>>>>>>> Turn off internal speaker.....\n"); -+ i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client); -+ //i2s_alc5630_write(0x02, 0x0000, g_i2c_client); -+ } -+ else { -+ //printk(">>>>>>>>>>>> Turn on internal speaker.....\n"); -+ i2s_alc5630_write(0x02, 0x0000, g_i2c_client); -+ //i2s_alc5630_write(0x02, 0x5F5F, g_i2c_client); -+ } -+ //End ADD by river 2011.03.23 -+ -+ -+ //printk("ftssp010_config() for I2S mode (Playback) ===> Dump register.\n"); -+ //i2s_alc5630_read_test(g_i2c_client); -+ } -+ -+#if 0 -+ /* Stuff TX fifo */ -+ while(ftssp010_tx_fifo_not_full(cardno)) { -+ outl(0x0, FTSSP010_DATA(cardno)); -+ } -+#endif -+} -+ -+void ftssp010_config_tx(int cardno, unsigned is_stereo, unsigned speed, int width) -+{ -+ return ftssp010_config(cardno, is_stereo, speed, width, 0); -+} -+ -+void ftssp010_config_rx(int cardno, unsigned is_stereo, unsigned speed, int width) -+{ -+ return ftssp010_config(cardno, is_stereo, speed, width, 1); -+} -+ -+/* Configures FTSSP010 to start TX. If use_dma being nonzero, -+ * FTSSP010 will use hardware handshake for DMA */ -+void ftssp010_start_tx(int cardno, unsigned use_dma) -+{ -+ unsigned bogus=0x800*3; -+ if(use_dma) { -+ /* Enable H/W DMA Request and set TX DMA threshold to 12*/ -+// outl(0xC022, FTSSP010_INT_CONTROL(cardno)); -+ outl(inl(FTSSP010_INT_CONTROL(cardno)) | 0xc422, FTSSP010_INT_CONTROL(cardno)); -+#if 0 -+ printk("%s: enable DMA request\n", __func__); -+#endif -+ } -+// outl(0x3, FTSSP010_CONTROL2(cardno)); -+ outl(inl(FTSSP010_CONTROL2(cardno)) | 0x3, FTSSP010_CONTROL2(cardno)); -+// printk("%s\n",__func__); -+// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); -+// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); -+ if(!use_dma) { -+ while(bogus>0) { -+ while(!ftssp010_tx_fifo_not_full(cardno)) -+ udelay(50); -+ outl(0, FTSSP010_DATA(cardno)); -+ bogus--; -+ } -+ } -+} -+ -+/* Configures FTSSP010 to start RX. If use_dma being nonzero, -+ * FTSSP010 will use hardware handshake for DMA */ -+void ftssp010_start_rx(int cardno, unsigned use_dma) -+{ -+ if(use_dma) { -+ /* Enable H/W DMA Request and set RX DMA threshold to 2*/ -+// outl(0x0111, FTSSP010_INT_CONTROL(cardno)); -+ outl(inl(FTSSP010_INT_CONTROL(cardno)) | 0xc411, FTSSP010_INT_CONTROL(cardno)); -+#if 0 -+ printk("%s: enable DMA request\n", __func__); -+#endif -+ } -+// outl(0x3, FTSSP010_CONTROL2(cardno)); -+ outl(inl(FTSSP010_CONTROL2(cardno)) | 0x3, FTSSP010_CONTROL2(cardno)); -+// printk("%s\n",__func__); -+// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); -+// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); -+} -+ -+void ftssp010_stop_tx(int cardno) -+{ -+// outl(0, FTSSP010_CONTROL2(cardno)); -+ outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x22), FTSSP010_INT_CONTROL(cardno)); -+// printk("%s\n",__func__); -+// printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); -+// printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); -+} -+ -+void ftssp010_stop_rx(int cardno) -+{ -+ //outl(0, FTSSP010_CONTROL2(cardno)); -+ outl(inl(FTSSP010_INT_CONTROL(cardno)) & (~0x11), FTSSP010_INT_CONTROL(cardno)); -+ //printk("%s\n",__func__); -+ //printk("int_control 0x%x\n",inl(FTSSP010_INT_CONTROL(cardno))); -+ //printk("control2 0x%x\n",inl(FTSSP010_CONTROL2(cardno))); -+} -+ -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_UDA1345TS.h linux-3.4.113/sound/nds32/FTSSP010_UDA1345TS.h ---- linux-3.4.113.orig/sound/nds32/FTSSP010_UDA1345TS.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_UDA1345TS.h 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,81 @@ -+/* FTSSP010 - UDA1345TS supporting library header */ -+/* -+ * -+ * $log$ -+ * -+ */ -+#include -+#include -+#include -+#include -+#include -+#include -+ -+/* Programming sequence: -+ * Suppose your playback format is 44.1KHz, 16 bit stereo -+ * PIO mode: -+ * pmu_set_i2s_clocking(44100); -+ * ftssp010_config(1, 44100, 0); -+ * ftssp010_start_tx(0); -+ * while(ftssp010_tx_fifo_not_full()) { -+ * Poke_your_PCM_data_to_FTSSP_data_port -+ * -+ * DMA mode: -+ * pmu_set_i2s_clocking(44100); -+ * ftssp010_config(1, 44100); -+ * -+ * pmu_set_i2s_dma_channel(ch); -+ * ftssp010_start_tx(1); -+ * -+ * ftssp010_stop_tx(); -+ */ -+#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) -+#define FTSSP010_DATA_PA(x) (SSP_FTSSP010_pa_base[(x)]+0x18) -+ -+/* Initialize FTSSP010 to output to UDA1345TS via I2S */ -+#define FTSSP010_CONTROL0(x) (SSP_FTSSP010_va_base[(x)]+0x0) -+#define FTSSP010_CONTROL0_OPM_STEREO 0xC -+#define FTSSP010_CONTROL0_OPM_MONO 0x8 -+ -+#define FTSSP010_CONTROL1(x) (SSP_FTSSP010_va_base[(x)]+0x4) -+#define FTSSP010_CONTROL2(x) (SSP_FTSSP010_va_base[(x)]+0x8) -+ -+#define FTSSP010_INT_CONTROL(x) (SSP_FTSSP010_va_base[(x)]+0x10) -+#define FTSSP010_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0xC) -+#define FTSSP010_INT_STATUS(x) (SSP_FTSSP010_va_base[(x)]+0x14) -+#define FTSSP010_DATA(x) (SSP_FTSSP010_va_base[(x)]+0x18) -+#define FTSSP010_INFO(x) (SSP_FTSSP010_va_base[(x)]+0x1C) -+ -+static const unsigned int SSP_FTSSP010_va_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_VA_BASE }; -+static const unsigned int SSP_FTSSP010_pa_base[SSP_FTSSP010_IRQ_COUNT] = { SSP_FTSSP010_PA_BASE }; -+ -+/* Drive PMU to generate I2S main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ -+extern void pmu_set_i2s_clocking(unsigned int speed); -+/* Programs PMU to set I2S/AC97 DMA Channel, ch=0-7 */ -+extern void pmu_set_i2s_dma_channel(unsigned ch); -+ -+/* Drive PMU to generate AC97 main clocking signal. Also configures PMU to set correct DMA REQ/ACK pair */ -+extern void pmu_set_ac97_clocking(unsigned int speed); -+ -+/* Returns FTSSP010 status */ -+extern void ftssp010_set_int_control(int cardno, unsigned val); -+extern int ftssp010_get_status(int cardno); -+extern unsigned ftssp010_get_int_status(int cardno); -+/* Polls FIFO full register */ -+extern int ftssp010_tx_fifo_not_full(int cardno); -+/* Configure FTSSP010 to a given sampling rate and channel number */ -+extern void ftssp010_config_tx(int cardno, unsigned is_stereo, unsigned speed, int use8bit); -+extern void ftssp010_config_rx(int cardno, unsigned is_stereo, unsigned speed, int use8bit); -+ -+/* Configure FTSSP010 to a given sampling rate and channel number */ -+extern void ftssp010_config_ac97_play(int cardno, unsigned is_stereo, unsigned speed, int use8bit); -+ -+extern void ftssp010_config_ac97_rec(int cardno, unsigned is_stereo, unsigned speed, int use8bit); -+ -+/* Initialize FTSSP010 to output to UDA1345TS via I2S */ -+extern void ftssp010_start_tx(int cardno, unsigned use_dma); -+extern void ftssp010_start_rx(int cardno, unsigned use_dma); -+extern void ftssp010_stop_tx(int cardno); -+extern void ftssp010_stop_rx(int cardno); -+ -+ -diff -Nur linux-3.4.113.orig/sound/nds32/FTSSP010_W83972D.h linux-3.4.113/sound/nds32/FTSSP010_W83972D.h ---- linux-3.4.113.orig/sound/nds32/FTSSP010_W83972D.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/FTSSP010_W83972D.h 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,17 @@ -+/* AC97 Codec related */ -+ -+ -+/* Register Index for Winbond W83972D AC97 Codec */ -+#define W83972D_RESET 0x0 -+#define W83972D_STEREO_OUTPUT_CONTROL 0x2 -+#define W83972D_MIC_VOLUME 0xE -+#define W83972D_LINE_IN_VOLUME 0x10 -+#define W83972D_AUX_INPUT_CONTROL 0x16 -+#define W83972D_PCM_OUTPUT_CONTROL 0x18 -+#define W83972D_RECORD_SELECT 0x1A -+#define W83972D_RECORD_GAIN 0x1C -+#define W83972D_RECORD_GAIN_MIC 0x1E -+#define W83972D_EXT_AUDIO_CONTROL 0x2A -+#define W83972D_DAC_SAMPLE_RATE_CONTROL 0x2C -+#define W83972D_VER1 0x7C -+#define W83972D_VER2 0x7E -diff -Nur linux-3.4.113.orig/sound/nds32/hda.h linux-3.4.113/sound/nds32/hda.h ---- linux-3.4.113.orig/sound/nds32/hda.h 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/hda.h 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,106 @@ -+// HDA Mode definition -+ #define HDA_MODE 0x80000000 -+ -+ // HDA CTRL definition -+ #define HDA_CRST_SET 0x00 -+ #define HDA_CRST_CLR 0x20 -+ #define HDA_CRST_MASK 0x20 -+ #define HDA_RST_FCNT_OFS 8 -+ -+ // HDA LNKST definition -+ #define HDA_COD_ALIVE 0x20000000 -+ -+ // HDA INTC definition -+ #define HDA_INTC_USOLEN 0x40000 -+ #define HDA_INTC_SDIWEN 0x20000 -+ #define HDA_INTC_CRINTE 0x10000 -+ -+ // HDA INTST definition -+ #define HDA_INTST_USOLEN 0x80 -+ #define HDA_INTST_SDIWEN 0x40 -+ #define HDA_INTST_CRINTE 0x20 -+ -+ // HDA ICMDST mask & offset -+ #define HDA_IRRADD_MASK 0xf0 -+ #define HDA_IRRUNSOL_MASK 0x08 -+ #define HDA_IRV_MASK 0x02 -+ #define HDA_ICB_MASK 0x01 -+ #define HDA_IRRADD_OFFSET 4 -+ #define HDA_IRRUNSOL_OFFSET 3 -+ #define HDA_IRV_OFFSET 1 -+ #define HDA_ICB_OFFSET 0 -+ //HDA OSDC/ISDC bit offset -+ #define HDA_SDC_STNUM_OFFSET 28 -+ #define HDA_SDC_SRUN_OFFSET 15 -+ #define HDA_SDC_BASE_OFFSET 14 -+ #define HDA_SDC_MULT_OFFSET 11 -+ #define HDA_SDC_DIV_OFFSET 8 -+ #define HDA_SDC_BITS_OFFSET 4 -+ #define HDA_SDC_CHAN_OFFSET 0 -+ -+ // HDA Codec CMD -+ #define HDA_COD_DEVADDR 0x00000000 -+ #define HDA_ROOT_NODE 0x00000000 -+ #define HDA_AUDIO_NODE 0x00100000 -+ #define HDA_OUTCOV_NODE 0x00200000 -+ //#define HDA_INCOV_NODE 0x0FF00000 -+ #define HDA_INCOV_NODE 0x00800000 //kane, for real CODEC node mapping -+ #define HDA_CMD_FGRST 0x0007FF00 -+ #define HDA_CMD_GETVID 0x000F0000 -+ #define HDA_CMD_SUBNCNT 0x000F0004 -+ #define HDA_CMD_FGTYPE 0x000F0005 -+ #define HDA_CMD_AUDIOWCAP 0x000F0009 -+ #define HDA_CMD_SETCVTSTR 0x00070600 -+ #define HDA_CMD_GETCVTSTR 0x000F0600 -+ #define HDA_CMD_SETCVTFMT 0x00020000 -+ #define HDA_CMD_GETCVTFMT 0x000A0000 -+ #define HDA_CMD_SETPROCST 0x00070300 -+ #define HDA_CMD_TRIGUNSOL 0x00070400 -+ //HDA Codec Resp -+ #define HDA_RESP_ZERO_VAL 0x00000000 -+ #define HDA_RESP_EXP_VID 0x10ec0888 -+ #define HDA_RSP_NODNUM_MSK 0xff0000 -+ #define HDA_RSP_NODCNT_MSK 0x0000ff -+ #define HDA_RSP_NODNUM_OFS 16 -+ #define HDA_RSP_NODCNT_OFS 0 -+ #define HDA_RSP_FGNTYPE_MSK 0xff -+ #define HDA_RSP_FGNUSCAP_MSK 0x100 -+ #define HDA_RSP_FGNTYPE_OFS 0 -+ #define HDA_RSP_FGNUSCAP_OFS 8 -+ #define HDA_RSP_AWCTYPE_MSK 0xf00000 -+ #define HDA_RSP_AWCUSCAP_MSK 0x000080 -+ #define HDA_RSP_AWCSTE_MSK 0x000001 -+ #define HDA_RSP_AWCTYPE_OFS 20 -+ #define HDA_RSP_AWCUSCAP_OFS 7 -+ #define HDA_RSP_AWCSTE_OFS 0 -+ #define HDA_RSP_CVTCHA_MSK 0x00 -+ #define HDA_RSP_CVTSTR_MSK 0xf0 -+ #define HDA_RSP_FMTTYPE_MSK 0x8000 -+ #define HDA_RSP_FMTBASE_MSK 0x4000 -+ #define HDA_RSP_FMTMULT_MSK 0x3800 -+ #define HDA_RSP_FMTDIV_MSK 0x0700 -+ #define HDA_RSP_FMTBITS_MSK 0x0070 -+ #define HDA_RSP_FMTCHNUM_MSK 0x000f -+ //HDA Func Group definition -+ #define HDA_FG_AUDIO 0x1 -+ // HDA Audio Widiget definition -+ #define HDA_AWC_INPUT 0x1 -+ #define HDA_AWC_OUTPUT 0x0 -+ #define HDA_AWC_MONO 0x0 -+ #define HDA_AWC_STEREO 0x1 -+ // HDA Converter Format definition -+ #define HDA_FMT_TYPE_OFS 15 -+ #define HDA_FMT_BASE_OFS 14 -+ #define HDA_FMT_MULT_OFS 11 -+ #define HDA_FMT_DIV_OFS 8 -+ #define HDA_FMT_BITS_OFS 4 -+ #define HDA_FMT_CHNUM_OFS 0 -+ // HDA Coverter Stream definition -+ #define HDA_STR_STR_OFS 4 -+ #define HDA_STR_CHA_OFS 0 -+ // HDA IOSDC definition -+ #define HDA_IN_STR 0 -+ #define HDA_OUT_STR 1 -+ #define HDA_STR_STOP 0 -+ #define HDA_STR_RUN 1 -+ -diff -Nur linux-3.4.113.orig/sound/nds32/Kconfig linux-3.4.113/sound/nds32/Kconfig ---- linux-3.4.113.orig/sound/nds32/Kconfig 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/Kconfig 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,22 @@ -+menu "ALSA NDS32 devices" -+ depends on SND!=n && NDS32 -+ -+config SND_FTSSP010 -+ tristate "Faraday FTSSP010 audio Driver" -+ depends on SND && NDS32 -+ select SND_PCM -+# select SND_AC97_CODEC -+ -+choice -+ prompt "AC97/I2S/HDA selection" -+ depends on SND_FTSSP010 -+ default SND_FTSSP010_AC97 -+config SND_FTSSP010_AC97 -+ bool "AC97" -+config SND_FTSSP010_I2S -+ bool "I2S" -+config SND_FTSSP010_HDA -+ bool "HDA" -+endchoice -+endmenu -+ -diff -Nur linux-3.4.113.orig/sound/nds32/Makefile linux-3.4.113/sound/nds32/Makefile ---- linux-3.4.113.orig/sound/nds32/Makefile 1970-01-01 01:00:00.000000000 +0100 -+++ linux-3.4.113/sound/nds32/Makefile 2016-12-01 20:59:24.396614447 +0100 -@@ -0,0 +1,10 @@ -+ifeq ($(CONFIG_SND_FTSSP010_AC97),y) -+snd-ftssp010-objs := FTSSP010_ALSA.o FTSSP010_lib.o -+endif -+ifeq ($(CONFIG_SND_FTSSP010_I2S),y) -+snd-ftssp010-objs := FTSSP010_ALSA.o FTSSP010_lib.o -+endif -+ifeq ($(CONFIG_SND_FTSSP010_HDA),y) -+snd-ftssp010-objs := FTSSP010_HDA.o FTSSP010_HDA_lib.o -+endif -+obj-$(CONFIG_SND_FTSSP010) += snd-ftssp010.o -diff -Nur linux-3.4.113.orig/arch/nds32/include/asm/sigcontext.h linux-3.4.113/arch/nds32/include/asm/sigcontext.h ---- linux-3.4.113.orig/arch/nds32/include/asm/sigcontext.h 2016-12-04 19:56:12.061027027 +0100 -+++ linux-3.4.113/arch/nds32/include/asm/sigcontext.h 2016-12-04 19:56:45.122305938 +0100 -@@ -59,7 +59,7 @@ - unsigned long nds32_r25; - unsigned long nds32_fp; /* $r28 */ - unsigned long nds32_gp; /* $r29 */ -- unsigned long nds32_lr; /* $r30 */ -+ unsigned long nds32_lp; /* $r30 */ - unsigned long nds32_sp; /* $r31 */ - unsigned long nds32_ipc; - unsigned long fault_address; -- cgit v1.2.3