2011-05-11 21:11:16

by Mark Salter

[permalink] [raw]
Subject: [PATCH] arch/c6x: new architecture port for linux

This patch series adds support for a new architecture (arch/c6x) to
Linux. This architecture supports members of the Texas Instruments
family of C64x single and multicore DSPs. The multicore DSPs do not
support cache coherancy, so are not suitable for SMP. Also, these are
no-mmu processors. This core architecture is VLIW with an instruction
set optimized for DSP applications. For details on the processors:

http://processors.wiki.ti.com/index.php/Main_Page

This port has a long history going back at least as far as 2.6.13 but
was never a good candidate for upstreaming due to lack of a gcc port.
These previous kernels were built with proprietary TI tools using COFF.
However, a gcc port now exists:

http://www.codesourcery.com/sgpp/lite/c6000/portal/release1783

Along with supporting the GNU toolchain work, Texas Instruments has also
been working on bringing the kernel port up to date and suitable for
contribution to the community. This is the start of that process and
hopefully we can quickly make whatever changes are necessary to get this
port included in the upstream kernel.

There are a few small patches to generic parts of the kernel including
bug fixes for a few generic headers. The most significant patch for the
generic kernel is the support for a new ELF based binary format called
DSBT. DSBT stands for Data Segment Base Table and provides a mechanism
for dynamic shared objects for systems without an MMU. In this regard it
is similar to the existing FDPIC support in the kernel but it uses a
very different approach. Whereas FDPIC ties data segment pointers to
function pointers, DSBT uses data accesses relativer to a dedicated
data pointer (DP) register. Each data segment in a DSO starts with a
table of DP values for each DSO linked into the process. Each DSO has
a unique index into that table. When a function call is made to another
DSO, the callee will save the current DP and retrieve its own DP from
the table indexed on the callee's known index. The advantage of this
over FDPIC is that function pointers require no special handling. The
main disadvantage is that DSOs in a system must have unique indices to
access their DP. These indices can be assigned at static link time when
the DSOs are built or later with a prelink-like tool when the rootfs is
composed.

The project wiki for linux-c6x is at:

http://www.linux-c6x.org

and the GIT tree holding the attached patches is at:

[email protected]:/git/projects/linux-c6x-upstreaming.git

TIA for any feedback and/or guidance on this port.


2011-05-11 21:11:49

by Mark Salter

[permalink] [raw]
Subject: [PATCH 01/16] fix default __strnlen_user macro

The existing __strnlen_user macro simply resolved to strnlen. However, the
count returned by strnlen_user should include the NULL byte. This patch
fixes the __strnlen_user macro to include the NULL byte in the count.

Signed-off-by: Mark Salter <[email protected]>
---
include/asm-generic/uaccess.h | 2 +-
1 files changed, 1 insertions(+), 1 deletions(-)

diff --git a/include/asm-generic/uaccess.h b/include/asm-generic/uaccess.h
index ac68c99..1d0fdf8 100644
--- a/include/asm-generic/uaccess.h
+++ b/include/asm-generic/uaccess.h
@@ -289,7 +289,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
* Return 0 on exception, a value greater than N if too long
*/
#ifndef __strnlen_user
-#define __strnlen_user strnlen
+#define __strnlen_user(s, n) (strnlen((s), (n)) + 1)
#endif

static inline long strnlen_user(const char __user *src, long n)
--
1.6.2.5

2011-05-11 21:06:43

by Mark Salter

[permalink] [raw]
Subject: [PATCH 02/16] fixed generic page.h for non-zero PAGE_OFFSET

asm-generic/page.h had several problems when used with a non-zero PAGE_OFFSET.
This patch adds a default ARCH_PFN_OFFSET and fixes the __va, __pa, and
pfn_valid macros to work with non-zero PAGE_OFFSETs.

Signed-off-by: Mark Salter <[email protected]>
---
include/asm-generic/page.h | 10 +++++++---
1 files changed, 7 insertions(+), 3 deletions(-)

diff --git a/include/asm-generic/page.h b/include/asm-generic/page.h
index 75fec18..f376db2 100644
--- a/include/asm-generic/page.h
+++ b/include/asm-generic/page.h
@@ -71,10 +71,14 @@ extern unsigned long memory_end;
#define PAGE_OFFSET (0)
#endif

+#ifndef ARCH_PFN_OFFSET
+#define ARCH_PFN_OFFSET (PAGE_OFFSET >> PAGE_SHIFT)
+#endif
+
#ifndef __ASSEMBLY__

-#define __va(x) ((void *)((unsigned long)(x) + PAGE_OFFSET))
-#define __pa(x) ((unsigned long) (x) - PAGE_OFFSET)
+#define __va(x) ((void *)((unsigned long) (x)))
+#define __pa(x) ((unsigned long) (x))

#define virt_to_pfn(kaddr) (__pa(kaddr) >> PAGE_SHIFT)
#define pfn_to_virt(pfn) __va((pfn) << PAGE_SHIFT)
@@ -86,7 +90,7 @@ extern unsigned long memory_end;
#define page_to_phys(page) ((dma_addr_t)page_to_pfn(page) << PAGE_SHIFT)
#endif

-#define pfn_valid(pfn) ((pfn) < max_mapnr)
+#define pfn_valid(pfn) ((pfn) >= ARCH_PFN_OFFSET && ((pfn) - ARCH_PFN_OFFSET) < max_mapnr)

#define virt_addr_valid(kaddr) (((void *)(kaddr) >= (void *)PAGE_OFFSET) && \
((void *)(kaddr) < (void *)memory_end))
--
1.6.2.5

2011-05-11 21:08:10

by Mark Salter

[permalink] [raw]
Subject: [PATCH 03/16] add driver for C64x+ ethernet driver

From: Aurelien Jacquiot <[email protected]>

This patch adds a network driver to support the ethernet interface found on
several Texas Instruments C64X+ based System on Chips. In particular, this
driver has been tested on the TMS320C6455, TMS320C6457, TMS320C6472, and
TMS320C6474 parts.

Signed-off-by: Aurelien Jacquiot <[email protected]>
Signed-off-by: Mark Salter <[email protected]>
---
drivers/net/Kconfig | 8 +
drivers/net/Makefile | 2 +
drivers/net/c6x_gemac.c | 1582 +++++++++++++++++++++++++++++++++++++++++++++++
drivers/net/c6x_gmdio.c | 514 +++++++++++++++
4 files changed, 2106 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/c6x_gemac.c
create mode 100644 drivers/net/c6x_gmdio.c

diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index dc280bc..5eb46a1 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2910,6 +2910,14 @@ config BNA

<http://support.brocade.com>

+config TMS320C64X_GEMAC
+ tristate "TMS320C64X GEMAC Ethernet Driver Support"
+ depends on TMS320C64XPLUS
+ default n
+ help
+ This driver supports the C64X+ SoC family ethernet
+ interface.
+
source "drivers/net/sfc/Kconfig"

source "drivers/net/benet/Kconfig"
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 01b604a..d768fde 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -259,6 +259,8 @@ obj-$(CONFIG_MLX4_CORE) += mlx4/
obj-$(CONFIG_ENC28J60) += enc28j60.o
obj-$(CONFIG_ETHOC) += ethoc.o
obj-$(CONFIG_GRETH) += greth.o
+obj-$(CONFIG_TMS320C64X_GEMAC) += gemac.o
+gemac-objs := c6x_gemac.o c6x_gmdio.o

obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o

diff --git a/drivers/net/c6x_gemac.c b/drivers/net/c6x_gemac.c
new file mode 100644
index 0000000..40124df
--- /dev/null
+++ b/drivers/net/c6x_gemac.c
@@ -0,0 +1,1582 @@
+/*
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2007, 2008, 2009, 2010 Texas Instruments Incorporated
+ * Authors: Nicolas Videau ([email protected])
+ * Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+#include <linux/spinlock.h>
+#include <linux/timer.h>
+#include <linux/platform_device.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/gmdio.h>
+#include <asm/gemac.h>
+
+#undef EMAC_DEBUG
+
+#ifdef EMAC_DEBUG
+#define DPRINTK(fmt, args...) printk(KERN_DEBUG "GEMAC: [%s] " fmt, __func__, ## args)
+#define ASSERT(cond) if (!(cond)) DPRINTK("ASSERT %s FAILURE\n", # cond)
+#else
+#define ASSERT(cond)
+#define DPRINTK(fmt, args...)
+#endif
+
+static int emac_open(struct net_device *dev);
+static int emac_close(struct net_device *dev);
+static int emac_reset(struct net_device *dev, int reset_mode);
+static void emac_set_modes(struct net_device *dev);
+static void emac_fixup_modes(struct net_device *dev);
+static void emac_reset_filter(struct net_device *dev,
+ int channel,
+ int reset_mode);
+static void emac_set_filter(struct net_device *dev, int channel);
+static int emac_reconfigure_device(struct net_device *dev);
+
+#ifdef EMAC_TIMER_TICK_MDIO
+static struct timer_list emac_timer;
+#endif
+
+static struct emac_config config = { 0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
+
+static int emac_shared;
+static int emac_idx;
+
+inline long _hex_chartol(char c)
+{
+ if (c >= '0' && c <= '9')
+ return c - '0';
+ if (c >= 'A' && c <= 'F')
+ return c - 'A' + 10;
+ if (c >= 'a' && c <= 'f')
+ return c - 'a' + 10;
+
+ return -1;
+}
+
+static unsigned long _hex_strtoul(const char *str, const char **end)
+{
+ unsigned long ul = 0;
+ long ud;
+ while ((ud = _hex_chartol(*str)) >= 0) {
+ ul = (ul << 4) | ud;
+ str++;
+ }
+ *end = str;
+ return ul;
+}
+
+static int __init get_mac_addr_from_cmdline(char *str)
+{
+ const char *start = (const char *) str;
+ const char *end;
+ int count;
+
+ for (count = 0; count < 6; count++) {
+ config.enetaddr[count] = _hex_strtoul(start, &end);
+ if (end == start)
+ return 0;
+ if ((*end != ':') && (count != 5))
+ return 0;
+ start = end + 1;
+ }
+ return 1;
+}
+
+__setup("emac_addr=", get_mac_addr_from_cmdline);
+
+static int __init set_emac_shared(char *str)
+{
+ emac_shared = 1;
+ return 1;
+}
+
+__setup("emac_shared", set_emac_shared);
+
+/*
+ * Get the device statistic
+ */
+static struct net_device_stats *emac_get_stats(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ unsigned int reg;
+ unsigned int dummy;
+ int i;
+
+ emac_set_stat(dev->stats.multicast, EMAC_RXMCASTFRAMES);
+ emac_set_stat(dev->stats.collisions, EMAC_TXCOLLISION);
+ emac_set_stat(dev->stats.rx_length_errors, EMAC_RXOVERSIZED);
+ emac_set_stat(dev->stats.rx_length_errors, EMAC_RXUNDERSIZED);
+ emac_set_stat(dev->stats.rx_crc_errors, EMAC_RXCRCERRORS);
+ emac_set_stat(dev->stats.rx_frame_errors, EMAC_RXALIGNCODEERRORS);
+ emac_set_stat(dev->stats.tx_carrier_errors, EMAC_TXCARRIERSLOSS);
+ emac_set_stat(dev->stats.tx_fifo_errors, EMAC_TXUNDERRUN);
+ emac_set_stat(dev->stats.tx_window_errors, EMAC_TXLATECOLL);
+
+ /* ACK statistic by write-to-decrement */
+ reg = EMAC_RXGOODFRAMES;
+ for (i = 0; i < EMAC_NUM_STATREGS; i++) {
+ dummy = emac_get_reg(reg);
+ emac_set_reg(reg, dummy);
+ reg += 4;
+ }
+
+ return &dev->stats;
+}
+
+/*
+ * Receive packets
+ */
+static int emac_rx(struct net_device *dev, struct emac_desc *desc_ack)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ volatile struct emac_desc *desc = ep->cur_rx;
+ ushort pkt_len;
+ u32 pkt_flags = desc->packet_flags_len & 0xffff0000;
+ int loop = 1;
+ struct sk_buff *skb, *skb_old;
+
+ DPRINTK("%s: RX desc_ack = 0x%x, cur_rx = 0x%x, num = %d\n",
+ dev->name, desc_ack, desc, (desc_ack - desc));
+
+ if ((desc == desc_ack) && (desc->packet_flags_len == EMAC_DESC_FLAG_OWNER))
+ loop = 0;
+
+ while (loop) {
+ skb_old = ep->rx_skbuff[ep->skb_rx_dirty];
+
+ pkt_len = desc->packet_flags_len & EMAC_PACKET_LEN_MASK;
+ pkt_flags = desc->packet_flags_len & 0xffff0000;
+
+ skb = netdev_alloc_skb_ip_align(dev, ep->packet_mtu);
+ if (skb != NULL) {
+ /* Prepare old sk_buff */
+ skb_old->dev = dev;
+ skb_put(skb_old, pkt_len);
+
+ /* No coherency is assumed between EDMA and L2 cache */
+ L2_cache_block_invalidate((u32) desc->buff,
+ (u32) desc->buff + pkt_len);
+
+ skb_old->protocol = eth_type_trans(skb_old, dev);
+
+ /* Attach new sk_buff to RX ring */
+ desc->buff = (u8 *) skb->data;
+ ep->rx_skbuff[ep->skb_rx_dirty] = skb;
+
+ DPRINTK("%s: receiving packet of %d len, proto 0x%x\n",
+ dev->name, pkt_len, skb->protocol);
+
+ /* Give back old sk_buff */
+ netif_rx(skb_old);
+ dev->last_rx = jiffies;
+
+ /* Fill statistic */
+ dev->stats.rx_packets++;
+ dev->stats.rx_bytes += pkt_len;
+ } else {
+ printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);
+ dev->stats.rx_dropped++;
+ }
+
+ /* Update RX dirty */
+ if (ep->skb_rx_dirty >= RX_RING_MOD_MAX)
+ ep->skb_rx_dirty = 0;
+ else
+ ep->skb_rx_dirty = ep->skb_rx_dirty + 1;
+
+ /* Descriptor is now available */
+ desc->buff_offset_len = ep->packet_mtu;
+ desc->packet_flags_len = EMAC_DESC_FLAG_OWNER;
+
+ /* Check if it is the last descriptor which has been received */
+ if (desc == desc_ack)
+ loop = 0;
+
+ /* Loop in the ring */
+ desc = HW_TO_PTR(desc->next);
+ }
+ ep->cur_rx = (struct emac_desc *) desc;
+
+ /* Check if the receiver stopped */
+ if (pkt_flags & EMAC_DESC_FLAG_EOQ)
+ emac_set_reg(EMAC_RX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
+ PTR_TO_HW((u32) ep->cur_rx));
+
+ return 0;
+}
+
+/*
+ * Transmit packets ACK
+ */
+static int emac_tx(struct net_device *dev, struct emac_desc *desc_ack)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ volatile struct emac_desc *desc = ep->dirty_tx;
+ int loop = 1;
+
+ while (loop) {
+ DPRINTK("%s: TX desc_ack = 0x%x, desc = 0x%x, num = %d\n",
+ dev->name, desc_ack, desc, (desc_ack - desc));
+
+ if (ep->tx_skbuff[ep->skb_tx_dirty] == NULL) {
+ printk(KERN_ERR "%s: SKB NULL desc =%p desc_ack =%p, skb_tx_dirty=%ld count=%ld\n",
+ dev->name, desc, desc_ack, ep->skb_tx_dirty, ep->count_tx);
+ break;
+ }
+
+ /* Free the skbuff associated to this packet */
+ dev_kfree_skb_irq(ep->tx_skbuff[ep->skb_tx_dirty]);
+
+ ep->tx_skbuff[ep->skb_tx_dirty] = NULL;
+ ep->skb_tx_dirty = (ep->skb_tx_dirty + 1) & TX_RING_MOD_MASK;
+ ep->count_tx--;
+
+ /* Check if it is the last acknowledged descriptor */
+ if (desc++ == desc_ack)
+ loop = 0;
+
+ /* Check end of the ring */
+ if (desc > ep->tx_desc_base + (TX_RING_SIZE - 1))
+ desc = ep->tx_desc_base;
+ }
+
+ if (netif_running(dev))
+ netif_wake_queue(dev);
+
+ /* Since we have freed up a buffer, the ring is no longer full */
+ if (ep->tx_full) {
+ ep->tx_full = 0;
+
+ DPRINTK("%s: wake up queue count_tx = %d cur_tx = 0x%x head_tx\n",
+ dev->name, ep->count_tx, ep->cur_tx, ep->head_tx);
+
+ if (netif_queue_stopped(dev))
+ netif_wake_queue(dev);
+ }
+
+ /* If this is the end of the queue */
+ if (desc_ack->packet_flags_len & EMAC_DESC_FLAG_EOQ) {
+
+ /* If there are some waiting packets, start the new queue */
+ if (ep->count_tx > 0)
+ emac_set_reg(EMAC_TX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
+ PTR_TO_HW(ep->head_tx));
+
+ /* Set the new head */
+ ep->head_tx = ep->cur_tx;
+ }
+
+ /* Update dirty tx */
+ ep->dirty_tx = (struct emac_desc *) desc;
+
+ return NETDEV_TX_OK;
+}
+
+/*
+ * Transmit the content of a skbuff
+ */
+static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ volatile struct emac_desc *desc;
+ volatile struct emac_desc *prev_desc = NULL;
+ ushort pkt_len = skb->len;
+ unsigned long flags;
+
+ if (ep->tx_full) {
+ printk(KERN_WARNING "%s: tx queue full\n", dev->name);
+ dev->stats.tx_dropped++;
+ return NETDEV_TX_BUSY;
+ }
+
+ /* Pad short frame */
+ if (unlikely(pkt_len < ETH_ZLEN)) {
+ if (skb_padto(skb, ETH_ZLEN)) {
+ netif_wake_queue(dev);
+ return NETDEV_TX_OK;
+ }
+ pkt_len = ETH_ZLEN;
+ }
+
+ spin_lock_irqsave(&ep->lock, flags);
+
+ desc = ep->cur_tx;
+
+ /* Set buffer length and pointer */
+ desc->buff = skb->data;
+ desc->packet_flags_len = pkt_len;
+ desc->buff_offset_len = pkt_len;
+ desc->next = NULL; /* close the queue*/
+
+ /* No coherency is assumed between EDMA and L2 cache */
+ L2_cache_block_writeback((u32) skb->data,
+ (u32) skb->data + pkt_len);
+
+ DPRINTK("%s: sending packet of %d len, skb_cur = %x, buffer = 0x%x\n",
+ dev->name, pkt_len, ep->skb_cur, skb->data);
+
+ /* Save skb */
+ ep->tx_skbuff[ep->skb_cur] = skb;
+ ep->skb_cur = (ep->skb_cur + 1) & TX_RING_MOD_MASK;
+ dev->stats.tx_packets++;
+ dev->stats.tx_bytes += pkt_len;
+ dev->trans_start = jiffies;
+
+ desc->packet_flags_len |= EMAC_DESC_FLAG_SOP
+ | EMAC_DESC_FLAG_EOP
+ | EMAC_DESC_FLAG_OWNER;
+
+ /* Get the previous element of the ring if we are not the head */
+ if (desc != ep->head_tx) {
+ if (desc == ep->tx_desc_base)
+ prev_desc = ep->tx_desc_base + (TX_RING_SIZE - 1);
+ else
+ prev_desc = desc - 1;
+
+ /* Link the buffer to the previous one in the list */
+ prev_desc->next = (struct emac_desc *) PTR_TO_HW(desc);
+ }
+
+ ep->count_tx++;
+
+ /* Update current pointer */
+ ep->cur_tx = (struct emac_desc *) desc + 1;
+
+ /* Check end of ring */
+ if (ep->cur_tx > ep->tx_desc_base + (TX_RING_SIZE - 1))
+ ep->cur_tx = ep->tx_desc_base;
+
+ /*
+ * If we are the new head and there is no descriptor to acknowledge, start
+ * the new head.
+ */
+ if ((desc == ep->head_tx) && (ep->count_tx == 1)) {
+ emac_set_reg(EMAC_TX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
+ PTR_TO_HW(ep->head_tx));
+ ep->head_tx = ep->cur_tx; /* set the new head */
+ }
+
+ /* Check ring oll over: do not reach the not yet acknowledged packets */
+ if (ep->count_tx == TX_RING_SIZE) {
+ ep->tx_full = 1;
+
+ DPRINTK("%s: tx queue full count_tx = %d cur_tx = 0x%x head_tx\n",
+ dev->name, ep->count_tx, ep->cur_tx, ep->head_tx);
+
+ netif_stop_queue(dev);
+ }
+ spin_unlock_irqrestore(&ep->lock, flags);
+
+ return NETDEV_TX_OK;
+}
+
+static void emac_handle_host_interrupt(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ unsigned long status;
+
+ /* Handle host error */
+ status = emac_get_reg(EMAC_MACSTATUS);
+
+ /* Check if the problem occurs on our channel when we are slave */
+ if ((ep->slave)
+ && (((status & EMAC_M_RXERRCH) >> EMAC_S_RXERRCH) != IDX_TO_CHAN(emac_idx))
+ && (((status & EMAC_M_TXERRCH) >> EMAC_S_TXERRCH) != IDX_TO_CHAN(emac_idx)))
+ return;
+
+ if ((status & EMAC_M_RXERRCODE) == (EMAC_V_OWNERSHIP << EMAC_S_RXERRCODE)) {
+ printk(KERN_ERR "%s: EMAC rx ring full\n", dev->name);
+ dev->stats.rx_fifo_errors++;
+ } else
+ printk(KERN_ERR "%s: EMAC fatal host error 0x%lx\n",
+ dev->name, status);
+
+ DPRINTK(KERN_ERR "%s: Error head=%p desc=%p dirty=%p skb_tx_dirty=%ld count=%ld\n",
+ dev->name, ep->head_tx, ep->cur_tx,
+ ep->dirty_tx, ep->skb_tx_dirty, ep->count_tx);
+
+ if (!ep->slave) {
+ /* Reconfigure the device */
+ ep->fatal_error = 1;
+ emac_reconfigure_device(dev);
+ }
+}
+
+/*
+ * Receive EMAC interrupt management
+ */
+
+#ifdef EMAC_HAS_SEPARATE_RXTX_IRQS
+
+static irqreturn_t emac_rx_interrupt(int irq, void *netdev_id)
+{
+ struct net_device *dev = netdev_id;
+ struct emac_private *ep = netdev_priv(dev);
+ struct emac_desc *desc;
+ unsigned long irq_flags;
+
+ ectl_arch_rx_irq_enter(IDX_TO_CHAN(emac_idx));
+
+ irq_flags = emac_arch_get_int_vector();
+
+ if (irq_flags & EMAC_B_STATPEND)
+ (void) emac_get_stats(dev);
+
+ if (irq_flags & EMAC_B_HOSTPEND)
+ emac_handle_host_interrupt(dev);
+
+ if (emac_arch_get_pending_irq(irq_flags,
+ EMAC_B_RXPEND0,
+ IDX_TO_CHAN(emac_idx))) {
+
+ /* ACK the interrupt */
+ desc = (struct emac_desc *) emac_get_reg(EMAC_RX0INTACK
+ + (IDX_TO_CHAN(emac_idx) << 2));
+ emac_set_reg(EMAC_RX0INTACK + (IDX_TO_CHAN(emac_idx) << 2), desc);
+
+ /* Handle receive event */
+ emac_rx(netdev_id, HW_TO_PTR(desc));
+ }
+
+ ectl_arch_rx_irq_leave(IDX_TO_CHAN(emac_idx));
+
+ return IRQ_HANDLED;
+}
+
+/*
+ * Transmit EMAC interrupt management
+ */
+static irqreturn_t emac_tx_interrupt(int irq, void *netdev_id)
+{
+ struct net_device *dev = netdev_id;
+ struct emac_private *ep = netdev_priv(dev);
+ struct emac_desc *desc;
+ unsigned long irq_flags;
+
+ ectl_arch_tx_irq_enter(IDX_TO_CHAN(emac_idx));
+
+ irq_flags = emac_arch_get_int_vector();
+
+ if (irq_flags & EMAC_B_STATPEND)
+ (void) emac_get_stats(dev);
+
+ if (irq_flags & EMAC_B_HOSTPEND)
+ emac_handle_host_interrupt(dev);
+
+ if (emac_arch_get_pending_irq(irq_flags,
+ EMAC_B_TXPEND0,
+ IDX_TO_CHAN(emac_idx))) {
+
+ /* ACK the interrupt */
+ desc = (struct emac_desc *) emac_get_reg(EMAC_TX0INTACK
+ + (IDX_TO_CHAN(emac_idx) << 2));
+ emac_set_reg(EMAC_TX0INTACK + (IDX_TO_CHAN(emac_idx) << 2), desc);
+
+ /* Handle transmit ACK event */
+ emac_tx(netdev_id, HW_TO_PTR(desc));
+ }
+
+ ectl_arch_tx_irq_leave(IDX_TO_CHAN(emac_idx));
+
+ return IRQ_HANDLED;
+}
+
+#else
+
+/*
+ * Main EMAC interrupt management
+ */
+static irqreturn_t emac_interrupt(int irq, void *netdev_id)
+{
+ struct net_device *dev = netdev_id;
+ struct emac_private *ep = netdev_priv(dev);
+ struct emac_desc *desc;
+ unsigned long irq_flags;
+
+ /* Disable EMAC/MDIO interrupts */
+ emac_clearbit_reg(EMAC_EWCTL, EMAC_B_INTEN);
+
+ irq_flags = emac_get_reg(EMAC_MACINVECTOR);
+
+ if (irq_flags & EMAC_B_STATPEND)
+ (void) emac_get_stats(dev);
+
+ if (irq_flags & EMAC_B_HOSTPEND) {
+ emac_handle_host_interrupt(dev);
+
+ /* EMAC/MDIO interrupts already enabled by emac_open() */
+ return IRQ_HANDLED;
+ }
+
+ if (irq_flags & EMAC_B_TXPEND0) {
+ /* ACK the interrupt */
+ desc = (struct emac_desc *) emac_get_reg(EMAC_TX0INTACK);
+ emac_set_reg(EMAC_TX0INTACK, desc);
+
+ /* Handle transmit ACK event */
+ emac_tx(netdev_id, desc);
+ }
+
+ if (irq_flags & EMAC_B_RXPEND0) {
+ /* ACK the interrupt */
+ desc = (struct emac_desc *) emac_get_reg(EMAC_RX0INTACK);
+ emac_set_reg(EMAC_RX0INTACK, desc);
+
+ /* Handle receive event */
+ emac_rx(netdev_id, desc);
+ }
+
+ /* Enable EMAC/MDIO interrupts */
+ emac_setbit_reg(EMAC_EWCTL, EMAC_B_INTEN);
+
+ return IRQ_HANDLED;
+}
+#endif
+
+#ifdef CONFIG_NET_POLL_CONTROLLER
+/*
+ * EMAC poll
+ */
+static void emac_poll(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ ectl_arch_disable_irq(IDX_TO_CHAN(emac_idx));
+
+#ifdef EMAC_HAS_SEPARATE_RXTX_IRQS
+ emac_tx_interrupt(dev->irq + 1, dev);
+ emac_rx_interrupt(dev->irq, dev);
+#else
+ emac_interrupt(dev->irq, dev);
+#endif
+
+ ectl_arch_enable_irq(IDX_TO_CHAN(emac_idx), !ep->slave);
+}
+#endif
+
+/*
+ * Register the MAC address
+ */
+
+static void emac_register_mac_addr(struct net_device *dev, int idx)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ u32 val;
+ int i;
+
+ /* Copy the config MAC address to the dev_addr */
+ for (i = 4; i >= 0; i--)
+ dev->dev_addr[i] = config.enetaddr[i];
+ /*
+ * Compute MAC addr low for all for the given EMAC instances if several.
+ * Each device consume n MAC addresses where n is the number cores.
+ * This value is for GEM0, this value + 2 is for GEM1, etc
+ * The number programmed in this field will be incremented by n * 2 from
+ * device to device
+ */
+ dev->dev_addr[5] = (config.enetaddr[5] +
+ (IDX_TO_MAC(idx)) + DEV_TO_MAC(dev->dev_id)) & 0xff;
+
+ /* Choose MAC address index between 0 and 31 */
+ emac_arch_set_mac_addr_index(idx);
+
+ /* Compute and store MAC addr high */
+ val = 0;
+ for (i = 3; i >= 0; i--)
+ val = (val << 8) | dev->dev_addr[i];
+ emac_arch_set_mac_addr_high(val);
+
+ val = (dev->dev_addr[5] << 8) | dev->dev_addr[4];
+ val |= (1 << EMAC_S_VALID)
+ | (1 << EMAC_S_MATCHFILTER)
+ | (IDX_TO_CHAN(idx) << EMAC_S_CHANNEL);
+
+ emac_arch_set_mac_addr_low(val);
+}
+
+/*
+ * Reset the EMAC software ring.
+ */
+static void emac_reset_ring(struct emac_private *ep)
+{
+ struct emac_desc *desc;
+ int i;
+
+ desc = (struct emac_desc *) ep->emac_dsc_base;
+
+ /* Reset rx ring */
+ ep->cur_rx = desc;
+ ep->skb_rx_dirty = 0;
+
+ for (i = 0; i < RX_RING_SIZE; desc++, i++)
+ desc->packet_flags_len = EMAC_DESC_FLAG_OWNER;
+
+ /* Reset tx ring */
+ desc = (struct emac_desc *) (ep->emac_dsc_base + (RX_RING_SIZE << 4));
+ ep->cur_tx = desc;
+ ep->dirty_tx = desc;
+ ep->head_tx = desc;
+ ep->skb_cur = 0;
+ ep->skb_tx_dirty = 0;
+ ep->tx_full = 0;
+ ep->fatal_error = 0;
+ ep->count_tx = 0;
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ desc->buff = NULL;
+ desc->buff_offset_len = 0;
+ desc->packet_flags_len = 0;
+ desc->next = NULL;
+ ep->tx_skbuff[i] = NULL;
+ desc++;
+ }
+}
+
+/*
+ * Reconfigure the EMAC device
+ */
+static int emac_reconfigure_device(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ if (!ep->slave) {
+ unsigned int hash1;
+ unsigned int hash2;
+ unsigned int promisc;
+ unsigned int control;
+ unsigned int rx_intmask;
+ unsigned int tx_intmask;
+ unsigned int unicast;
+ unsigned int *mac_ctx;
+ int i;
+
+ /* Get state */
+ hash1 = emac_arch_get_hash1();
+ hash2 = emac_arch_get_hash2();
+ promisc = emac_arch_get_promisc();
+ control = emac_arch_get_control();
+
+ unicast = emac_get_reg(EMAC_RXUNICASTSET);
+ rx_intmask = emac_get_reg(EMAC_RXINTMASKSET);
+ tx_intmask = emac_get_reg(EMAC_TXINTMASKSET);
+
+ /* Save MAC addresses */
+ mac_ctx = kmalloc((sizeof(u32) << 1) * MAC_ADDR_NUM, GFP_KERNEL);
+ for (i = 0; i < MAC_ADDR_NUM; i++) {
+ emac_arch_set_mac_addr_index(i);
+ mac_ctx[i << 1] = emac_arch_get_mac_addr_high();
+ mac_ctx[(i << 1) + 1] = emac_arch_get_mac_addr_low();
+ }
+
+ /* Reset the EMAC */
+ if (netif_running(dev)) {
+ emac_close(dev);
+ emac_reset(dev, GEMAC_RESET_WARM);
+ emac_open(dev);
+ } else {
+ emac_reset(dev, GEMAC_RESET_WARM);
+ }
+
+ /* Restore MAC addresses */
+ for (i = 0; i < MAC_ADDR_NUM; i++) {
+ emac_arch_set_mac_addr_index(i);
+ emac_arch_set_mac_addr_high(mac_ctx[i << 1]);
+ emac_arch_set_mac_addr_low(mac_ctx[(i << 1) + 1]);
+ }
+ kfree(mac_ctx);
+
+ /* Restore state */
+ emac_arch_set_hash1(hash1);
+ emac_arch_set_hash2(hash2);
+ emac_arch_set_promisc(hash2);
+ emac_arch_set_control(hash2);
+
+ emac_set_reg(EMAC_RXINTMASKSET, rx_intmask);
+ emac_set_reg(EMAC_TXINTMASKSET, tx_intmask);
+ emac_set_reg(EMAC_RXUNICASTSET, unicast);
+ } else
+ /* Only master core can reset the device */
+ return -EBUSY;
+
+ return 0;
+}
+
+/*
+ * Reset the EMAC hardware.
+ */
+static int emac_reset(struct net_device *dev, int reset_mode)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ volatile u32 *preg;
+ int i;
+
+ if (!ep->slave) {
+
+ if (reset_mode == GEMAC_RESET_COLD) {
+ /* Reset integrated switch if any */
+ emac_arch_reset_switch();
+
+ /* Reset EMAC control Module */
+ emac_arch_reset_ectl();
+ }
+
+ /* Reset EMAC */
+ emac_setbit_reg(EMAC_SOFTRESET, EMAC_B_SOFTRST);
+
+ /* Wait until reset has occured or timeout */
+ for (i = 0; i <= HZ / 2; i++) {
+ if (emac_get_reg(EMAC_SOFTRESET) == 0x0)
+ break;
+ if (i == HZ / 2)
+ return 1;
+ msleep_interruptible(1);
+ }
+ }
+
+ /* Set interrupt pacing */
+ emac_arch_set_pacing();
+
+ if (!ep->slave) {
+ /* Reset MAC, TX, RX Control */
+ emac_set_reg(EMAC_MACCONTROL, 0);
+ emac_set_reg(EMAC_TXCONTROL, 0);
+ emac_set_reg(EMAC_RXCONTROL, 0);
+
+ if (reset_mode == GEMAC_RESET_COLD) {
+#ifdef EMAC_DO_INIT_MDIO
+ /* MII/MDIO setup */
+ mdio_init(emac_get_reg(EMAC_TXIDVER));
+#endif
+
+ /* Init HDPs to NULL for all channels */
+ emac_set_reg(EMAC_TX0HDP, 0);
+ emac_set_reg(EMAC_TX1HDP, 0);
+ emac_set_reg(EMAC_TX2HDP, 0);
+ emac_set_reg(EMAC_TX3HDP, 0);
+ emac_set_reg(EMAC_TX4HDP, 0);
+ emac_set_reg(EMAC_TX5HDP, 0);
+ emac_set_reg(EMAC_TX6HDP, 0);
+ emac_set_reg(EMAC_TX7HDP, 0);
+ emac_set_reg(EMAC_RX0HDP, 0);
+ emac_set_reg(EMAC_RX1HDP, 0);
+ emac_set_reg(EMAC_RX2HDP, 0);
+ emac_set_reg(EMAC_RX3HDP, 0);
+ emac_set_reg(EMAC_RX4HDP, 0);
+ emac_set_reg(EMAC_RX5HDP, 0);
+ emac_set_reg(EMAC_RX6HDP, 0);
+ emac_set_reg(EMAC_RX7HDP, 0);
+
+ /* Clear statistic registers */
+ if (reset_mode == GEMAC_RESET_COLD) {
+ preg = emac_addr_reg(EMAC_RXGOODFRAMES);
+ for (i = 0; i < EMAC_NUM_STATREGS; i++)
+ *preg++ = 0;
+ }
+
+ /* Clear all MAC addresses */
+ emac_arch_clear_mac_addr();
+ }
+ }
+
+ /* Register my MAC address */
+ emac_register_mac_addr(dev, emac_idx);
+
+ if (!ep->slave) {
+
+ /* Used for pause frame (IEEE 802.3x) but not working for MC */
+ emac_set_reg(EMAC_MACSRCADDRLO,
+ (dev->dev_addr[0] << 8) | dev->dev_addr[1]);
+ emac_set_reg(EMAC_MACSRCADDRHI,
+ (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
+ (dev->dev_addr[4] << 8) | (dev->dev_addr[5]));
+
+ if (reset_mode == GEMAC_RESET_COLD) {
+
+ /* Init completion pointers to NULL */
+ emac_set_reg(EMAC_RX0INTACK, 0x0);
+ emac_set_reg(EMAC_RX1INTACK, 0x0);
+ emac_set_reg(EMAC_RX2INTACK, 0x0);
+ emac_set_reg(EMAC_RX3INTACK, 0x0);
+ emac_set_reg(EMAC_RX4INTACK, 0x0);
+ emac_set_reg(EMAC_RX5INTACK, 0x0);
+ emac_set_reg(EMAC_RX6INTACK, 0x0);
+ emac_set_reg(EMAC_RX7INTACK, 0x0);
+ emac_set_reg(EMAC_TX0INTACK, 0x0);
+ emac_set_reg(EMAC_TX1INTACK, 0x0);
+ emac_set_reg(EMAC_TX2INTACK, 0x0);
+ emac_set_reg(EMAC_TX3INTACK, 0x0);
+ emac_set_reg(EMAC_TX4INTACK, 0x0);
+ emac_set_reg(EMAC_TX5INTACK, 0x0);
+ emac_set_reg(EMAC_TX6INTACK, 0x0);
+ emac_set_reg(EMAC_TX7INTACK, 0x0);
+ }
+
+ /* Reset unicast, multicast, broadcast Rx */
+ emac_reset_filter(dev, IDX_TO_CHAN(emac_idx), reset_mode);
+
+ /* Set device modes */
+ emac_set_modes(dev);
+
+ /* Disable all channel interrupts */
+ if (reset_mode == GEMAC_RESET_COLD) {
+ emac_set_reg(EMAC_RXINTMASKCLEAR, 0xff);
+ emac_set_reg(EMAC_TXINTMASKCLEAR, 0xff);
+ }
+
+ /* Enable host and stat interrupts */
+ emac_set_reg(EMAC_MACINTMASKSET, EMAC_B_HOSTINT | EMAC_B_STATINT);
+ } else {
+ /* Fixup mode according to hw configuration */
+ emac_fixup_modes(dev);
+ }
+
+ /* Enable TX and RX interrupts for a given channel */
+ emac_arch_enable_irq(EMAC_TXINTMASKSET, IDX_TO_CHAN(emac_idx));
+ emac_arch_enable_irq(EMAC_RXINTMASKSET, IDX_TO_CHAN(emac_idx));
+
+ /* Reset transmit/receive buffers */
+ if (reset_mode == GEMAC_RESET_WARM)
+ (void) emac_reset_ring(ep);
+
+ /* Set default receive filter: unicast, multicast and broadcast */
+ emac_set_filter(dev, IDX_TO_CHAN(emac_idx));
+
+ return 0;
+}
+
+/*
+ * Open the device
+ */
+static int emac_open(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ if (!ep->slave) {
+ /* Set MAC mode (Gigabyte, xxMII, pacing, etc) */
+ emac_arch_init_control(ep->mode_flags & EMAC_CONFIG_PACING);
+
+ /* Enable RX and TX */
+ emac_set_reg(EMAC_TXCONTROL, 1);
+ emac_set_reg(EMAC_RXCONTROL, 1);
+ }
+
+ /* Ready for RX */
+ emac_set_reg(EMAC_RX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
+ PTR_TO_HW(ep->cur_rx));
+
+ /* Enable interrupts at the ECTL level (misc int only for master) */
+ ectl_arch_enable_irq(IDX_TO_CHAN(emac_idx), !ep->slave);
+
+ netif_start_queue(dev);
+
+ return 0;
+}
+
+/*
+ * Close the device
+ */
+static int emac_close(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ netif_stop_queue(dev);
+
+ /* Disable interrupt at the ECTL level */
+ ectl_arch_disable_irq(IDX_TO_CHAN(emac_idx));
+
+ /* Teardown RX and TX */
+ emac_set_reg(EMAC_RXTEARDOWN, IDX_TO_CHAN(emac_idx));
+ emac_set_reg(EMAC_TXTEARDOWN, IDX_TO_CHAN(emac_idx));
+
+ if (!ep->fatal_error) {
+ unsigned int tmp;
+
+ /* Wait for the teardown to complete */
+ for (tmp = 0; tmp != 0xfffffffc;
+ tmp = emac_get_reg(EMAC_RX0INTACK + \
+ (IDX_TO_CHAN(emac_idx) << 2)))
+ emac_set_reg(EMAC_RX0INTACK + \
+ (IDX_TO_CHAN(emac_idx) << 2), tmp);
+
+ for (tmp = 0; tmp != 0xfffffffc;
+ tmp = emac_get_reg(EMAC_TX0INTACK + \
+ (IDX_TO_CHAN(emac_idx) << 2)))
+ emac_set_reg(EMAC_TX0INTACK + \
+ (IDX_TO_CHAN(emac_idx) << 2), tmp);
+ }
+
+ if (!ep->slave) {
+ /* Disable Rx, Tx and MII */
+ emac_set_reg(EMAC_TXCONTROL, 0);
+ emac_set_reg(EMAC_RXCONTROL, 0);
+ emac_set_reg(EMAC_MACCONTROL, 0);
+ }
+
+ /* Clean up the software ring */
+ emac_reset_ring(ep);
+
+ return 0;
+}
+
+/*
+ * Initialize the EMAC software ring.
+ * For the rx ring, we initialize the packet descriptors with pre-allocated
+ * skbuff to the packet MTU size.
+ * For the tx ring, we only initialize it with NULL values.
+ */
+static int emac_setup_ring(struct emac_private *ep)
+{
+ struct emac_desc *desc;
+ int i;
+ struct sk_buff *skb;
+
+ /* Setup rx ring*/
+ desc = (struct emac_desc *) ep->emac_dsc_base;
+ ep->rx_desc_base = desc;
+ ep->cur_rx = desc;
+ ep->skb_rx_dirty = 0;
+
+ /* Allocate ring buffers via sk buffers */
+ for (i = 0; i < RX_RING_SIZE; i++) {
+ skb = netdev_alloc_skb_ip_align(ep->dev, ep->packet_mtu);
+ if (!skb)
+ return 1;
+
+ ep->rx_skbuff[i] = skb;
+ desc->buff = (u8 *) skb->data;
+ desc->buff_offset_len = ep->packet_mtu;
+ desc->packet_flags_len = EMAC_DESC_FLAG_OWNER;
+ desc->next = PTR_TO_HW(desc + 1);
+ desc++;
+ }
+
+ /* Loop the ring */
+ (desc - 1)->next = PTR_TO_HW(ep->rx_desc_base);
+
+ /* Setup tx ring */
+ desc = (struct emac_desc *) (ep->emac_dsc_base + (RX_RING_SIZE << 4));
+ ep->tx_desc_base = desc;
+ ep->cur_tx = desc;
+ ep->dirty_tx = desc;
+ ep->head_tx = desc;
+ ep->skb_cur = 0;
+ ep->skb_tx_dirty = 0;
+ ep->tx_full = 0;
+ ep->fatal_error = 0;
+ ep->count_tx = 0;
+
+ for (i = 0; i < TX_RING_SIZE; i++) {
+ desc->buff = NULL;
+ desc->buff_offset_len = 0;
+ desc->packet_flags_len = 0;
+ desc->next = NULL;
+ ep->tx_skbuff[i] = NULL;
+ desc++;
+ }
+ return 0;
+}
+
+/*
+ * Called by the kernel to send a packet out into the void
+ * of the net.
+ */
+static void emac_timeout(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
+ dev->stats.tx_errors++;
+ dev->trans_start = jiffies;
+ if (!ep->tx_full)
+ netif_wake_queue(dev);
+}
+
+/*
+ * Set or clear the multicast filter for this adaptor.
+ */
+#ifdef EMAC_HAS_ALE_SUPPORT
+static void emac_reset_filter(struct net_device *dev,
+ int channel,
+ int reset_mode)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ int i;
+
+ if (reset_mode == GEMAC_RESET_COLD) {
+ /* Alloc mcast list */
+ ep->mcast_infos = kmalloc(3 * EMAC_V_ALE_MAX_MCAST, GFP_KERNEL);
+ /* Init mcast table */
+ if (ep->mcast_infos) {
+ memset(ep->mcast_infos, 0x0, 3 * EMAC_V_ALE_MAX_MCAST);
+ /* Clear device multicast list */
+ for (i = 0; i < EMAC_V_ALE_MAX_MCAST; i++) {
+ emac_set_reg(EMAC_ALETBLW0, 0);
+ emac_set_reg(EMAC_ALETBLW1, 0);
+ emac_set_reg(EMAC_ALETBLW2, 0);
+ emac_set_reg(EMAC_ALETBLCTL,
+ i | EMAC_B_ALE_WRITE_RDZ);
+ }
+ }
+ }
+ if ((reset_mode == GEMAC_RESET_WARM) && (ep->mcast_infos)) {
+ /* Re-set device multicast list */
+ for (i = 0; i < ep->mcast_valid_len; i++) {
+ emac_set_reg(EMAC_ALETBLW0, ep->mcast_infos[3*i]);
+ emac_set_reg(EMAC_ALETBLW1, ep->mcast_infos[3*i+1]);
+ emac_set_reg(EMAC_ALETBLW2, ep->mcast_infos[3*i+2]);
+ emac_set_reg(EMAC_ALETBLCTL,
+ i | EMAC_B_ALE_WRITE_RDZ);
+ }
+ /* Set mcast mode if needed */
+ if (ep->mcast_valid_len)
+ emac_setbit_reg(EMAC_ALEUNKNOWNVLAN,
+ EMAC_B_REG_MCAST_FLOOD_ON);
+ }
+}
+
+static void emac_set_modes(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ if (ep->mode_flags & EMAC_CONFIG_RXCRC)
+ ep->packet_mtu = PKT_MTU_CRC;
+ else
+ ep->packet_mtu = PKT_MTU_NOCRC;
+
+ /* If PASSERROR is set, enable both ERROR and short frames */
+ if (ep->mode_flags & EMAC_CONFIG_PASSERROR)
+ emac_setbit_reg(EMAC_MACCONTROL,
+ EMAC_B_RXCEFEN | EMAC_B_RXCSFEN);
+
+ /* If PASSCONTROL is set, enable control frames */
+ if (ep->mode_flags & EMAC_CONFIG_PASSCONTROL)
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_RXCMFEN);
+
+ /* Set MAC loopback if requested */
+ if (ep->mode_flags & EMAC_CONFIG_MACLOOPBACK)
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_LOOPBACK);
+}
+
+static void emac_set_filter(struct net_device *dev, int channel)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ emac_set_reg(CPSW_SW_CTL, 0x000000F4); /* Enable switch flow control */
+ emac_set_reg(CPSW_RX_CH_MAP, 0x11110000); /* RX switch priority */
+
+ emac_set_reg(EMAC_ALECONTROL, 0x80000004); /* ALE enable and bypass */
+ emac_set_reg(EMAC_ALEPRESCALE, 0x0); /* no mcat/broadcast limit */
+ emac_set_reg(EMAC_ALEUNKNOWNVLAN, 0x07030307); /* need it!!! */
+ emac_set_reg(EMAC_ALEPORTCTL0, 0x3); /* Port 0 in forward state */
+ emac_set_reg(EMAC_ALEPORTCTL1, 0x3); /* Port 1 in forward state */
+ emac_set_reg(EMAC_ALEPORTCTL2, 0x3); /* Port 2 in forward state */
+}
+
+static void emac_set_rx_mode(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ struct dev_mc_list *dmi = dev->mc_list;
+ u8 hashval, tmpval;
+ u32 info0, info1, info2;
+ int i;
+
+ /* Only master can use promiscuous or multicast */
+ if (ep->slave)
+ return;
+
+ if (dev->flags & IFF_PROMISC)
+ /* Set promiscuous mode */
+ emac_setbit_reg(EMAC_ALECONTROL, EMAC_B_ALEBYPASS);
+ else
+ /* Reset promiscuous mode */
+ emac_clearbit_reg(EMAC_ALECONTROL, EMAC_B_ALEBYPASS);
+
+ /* Clear multicast config */
+ emac_clearbit_reg(EMAC_ALEUNKNOWNVLAN, EMAC_B_MCAST_FLOOD_ON |
+ EMAC_B_REG_MCAST_FLOOD_ON);
+
+ /* Clear old multicast list that will not be reused */
+ for (i = dev->mc_count; i < ep->mcast_valid_len; i++) {
+ emac_setbit_reg(EMAC_ALETBLW0, 0);
+ emac_setbit_reg(EMAC_ALETBLW1, 0);
+ emac_setbit_reg(EMAC_ALETBLW2, 0);
+ emac_setbit_reg(EMAC_ALETBLCTL,
+ i | EMAC_B_ALE_WRITE_RDZ);
+ }
+
+ if ((dev->flags & IFF_ALLMULTI) ||
+ (dev->mc_count > EMAC_V_ALE_MAX_MCAST)) {
+ /* Set all multicast */
+ emac_setbit_reg(EMAC_ALEUNKNOWNVLAN, EMAC_B_MCAST_FLOOD_ON |
+ EMAC_B_REG_MCAST_FLOOD_ON);
+ } else {
+ /* Set mcast from a list */
+ for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) {
+ u8 *p_dmi = dmi->dmi_addr;
+
+ info0 = (((p_dmi[2]&0x0ff)<<24) |
+ ((p_dmi[3]&0x0ff)<<16) |
+ ((p_dmi[4]&0x0ff)<<8) | ((p_dmi[5]&0x0ff)<<0));
+ info1 = ((3<<30) | (0<<29) | (1<<28) |
+ ((0&0x0fff)<<16) |
+ ((p_dmi[0]&0x0ff)<<8) | ((p_dmi[1]&0x0ff)<<0));
+ info2 = (0 << 3) | (7 & 0x7);
+
+ /* Only support group multicast */
+ if (!(*p_dmi & 1)) {
+ /* don't use this entry */
+ info0 = 0;
+ info1 = 1;
+ info2 = 2;
+ }
+
+ emac_set_reg(EMAC_ALETBLW0, info0);
+ emac_set_reg(EMAC_ALETBLW1, info1);
+ emac_set_reg(EMAC_ALETBLW2, info2);
+ emac_set_reg(EMAC_ALETBLCTL,
+ i | EMAC_B_ALE_WRITE_RDZ);
+
+ /* Copy mcast list */
+ if (ep->mcast_infos) {
+ ep->mcast_infos[3*i] = info0;
+ ep->mcast_infos[3*i+1] = info1;
+ ep->mcast_infos[3*i+2] = info2;
+ }
+ }
+
+ /* set multicast mode if needed */
+ if (dev->mc_count)
+ emac_setbit_reg(EMAC_ALEUNKNOWNVLAN,
+ EMAC_B_REG_MCAST_FLOOD_ON);
+
+ /* Remember mcast valid addrs count */
+ ep->mcast_valid_len = dev->mc_count;
+ }
+}
+
+#else /* !EMAC_HAS_ALE_SUPPORT */
+
+static void emac_reset_filter(struct net_device *dev,
+ int channel,
+ int reset_mode)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ /* Reset multicast hash table */
+ emac_set_reg(EMAC_MACHASH1, 0);
+ emac_set_reg(EMAC_MACHASH2, 0);
+
+ /* Set buffer offset */
+ emac_set_reg(EMAC_RXBUFFEROFFSET, 0);
+
+ /* Reset RX (M)ulticast (B)roadcast (P)romiscuous Enable register */
+ emac_set_reg(EMAC_RXMBPENABLE, 0);
+
+ if (reset_mode == GEMAC_RESET_COLD) {
+ /* Clear unicast RX on channel 0-7 */
+ emac_set_reg(EMAC_RXUNICASTCLEAR, 0xff);
+ } else
+ emac_set_reg(EMAC_RXUNICASTCLEAR, (1 << channel));
+}
+
+static void emac_fixup_modes(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ if (emac_get_reg(EMAC_RXMBPENABLE) & EMAC_B_RXPASSCRC)
+ ep->packet_mtu = PKT_MTU_CRC;
+ else
+ ep->packet_mtu = PKT_MTU_NOCRC;
+}
+
+static void emac_set_modes(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ if (ep->slave)
+ return;
+
+ if (ep->mode_flags & EMAC_CONFIG_RXCRC) {
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXPASSCRC);
+ ep->packet_mtu = PKT_MTU_CRC;
+ } else
+ ep->packet_mtu = PKT_MTU_NOCRC;
+
+ /* If PASSERROR is set, enable both ERROR and short frames */
+ if (ep->mode_flags & EMAC_CONFIG_PASSERROR)
+ emac_setbit_reg(EMAC_RXMBPENABLE,
+ EMAC_B_RXCEFEN | EMAC_B_RXCSFEN);
+
+ /* If PASSCONTROL is set, enable control frames */
+ if (ep->mode_flags & EMAC_CONFIG_PASSCONTROL)
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCMFEN);
+
+ /* Set the channel configuration to priority if requested */
+ if (ep->mode_flags & EMAC_CONFIG_CHPRIORITY)
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_TXPTYPE);
+
+ /* Set MAC loopback if requested */
+ if (ep->mode_flags & EMAC_CONFIG_MACLOOPBACK)
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_LOOPBACK);
+}
+
+static void emac_set_filter(struct net_device *dev, int channel)
+{
+ struct emac_private *ep = netdev_priv(dev);
+
+ /* Set unicast for the given channel */
+ emac_set_reg(EMAC_RXUNICASTSET, 1 << channel);
+
+ if (!ep->slave) {
+ emac_set_reg(EMAC_RXMBPENABLE, 0);
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_MULTEN);
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_BROADEN);
+ emac_setbit_reg(EMAC_RXMBPENABLE, (channel | (channel << 8)));
+ }
+}
+
+static void emac_set_rx_mode(struct net_device *dev)
+{
+ struct emac_private *ep = netdev_priv(dev);
+ struct netdev_hw_addr *ha;
+ u8 hashval, tmpval;
+ u32 machash1, machash2;
+ int i;
+
+ /* Only master can use promiscuous or multicast */
+ if (ep->slave)
+ return;
+
+ if (dev->flags & IFF_PROMISC) {
+ /* Set promiscuous mode */
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN);
+ } else {
+ /* Reset promiscuous mode */
+ emac_clearbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN);
+ }
+
+ if (dev->flags & IFF_ALLMULTI) {
+
+ /* Set all multicast filter */
+ emac_setbit_reg(EMAC_MACHASH1, 0xffffffff);
+ emac_setbit_reg(EMAC_MACHASH2, 0xffffffff);
+
+ } else {
+
+ hashval = 0;
+ machash1 = 0;
+ machash2 = 0;
+
+ netdev_for_each_mc_addr(ha, dev) {
+ u8 *addr = ha->addr;
+
+ /* Only support group multicast */
+ if (!(*addr & 1))
+ continue;
+
+ for (i = 0; i < 2; i++) {
+ tmpval = (u8) *addr++;
+ hashval ^= (u8) (tmpval >> 2) ^ (tmpval << 4);
+ tmpval = (u8) *addr++;
+ hashval ^= (u8) (tmpval >> 4) ^ (tmpval << 2);
+ tmpval = (u8) *addr++;
+ hashval ^= (u8) (tmpval >> 6) ^ (tmpval);
+ }
+
+ if (hashval & 0x20)
+ machash2 |= (1 << (hashval & 0x1f));
+ else
+ machash1 |= (1 << (hashval & 0x1f));
+ }
+
+ /* Set computed multicast filter */
+ emac_setbit_reg(EMAC_MACHASH1, machash1);
+ emac_setbit_reg(EMAC_MACHASH2, machash2);
+ }
+}
+#endif /* !EMAC_HAS_ALE_SUPPORT */
+
+#ifdef EMAC_TIMER_TICK_MDIO
+/*
+ * This function should be called for each device in the system on a
+ * periodic basis of 100mS (10 times a second). It is used to check the
+ * status of the EMAC and MDIO device.
+ */
+static void emac_timer_tick(unsigned long data)
+{
+ struct net_device *dev = (struct net_device *)data;
+ struct emac_private *ep = netdev_priv(dev);
+ unsigned int link_status;
+ unsigned int link_event = mdio_timer_tick();
+ unsigned int intfmacsel = mdio_get_macsel();
+
+ /*
+ * Signal the MDIO
+ */
+ if (link_event == MDIO_EVENT_LINKUP) {
+ link_status = mdio_get_status();
+ if (link_status == MDIO_LINKSTATUS_FD10 ||
+ link_status == MDIO_LINKSTATUS_FD100 ||
+ link_status == MDIO_LINKSTATUS_FD1000) {
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_FULLDUPLEX);
+ if (intfmacsel == DEVSTAT_MACSEL_RMII)
+ emac_setbit_reg(EMAC_MACCONTROL,
+ EMAC_B_RMIIDUPLEXMODE);
+ } else {
+ emac_clearbit_reg(EMAC_MACCONTROL, EMAC_B_FULLDUPLEX);
+ if (intfmacsel == DEVSTAT_MACSEL_RMII)
+ emac_clearbit_reg(EMAC_MACCONTROL,
+ EMAC_B_RMIIDUPLEXMODE);
+ }
+
+ if (link_status == MDIO_LINKSTATUS_FD1000)
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_GIG);
+
+ if ((link_status == MDIO_LINKSTATUS_FD10 ||
+ link_status == MDIO_LINKSTATUS_HD10) &&
+ (intfmacsel == DEVSTAT_MACSEL_RMII))
+ /* Clear bit to set clock to 2.5 MHz */
+ emac_clearbit_reg(EMAC_MACCONTROL, EMAC_B_RMIISPEED);
+
+ if ((link_status == MDIO_LINKSTATUS_FD100 ||
+ link_status == MDIO_LINKSTATUS_HD100) &&
+ (intfmacsel == DEVSTAT_MACSEL_RMII))
+ /* Set bit to set clock to 25 MHz */
+ emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_RMIISPEED);
+
+ /* eventually call platform hook for RMII out of reset */
+ rmii_arch_fix();
+
+ /* Put RGMII in forced link mode */
+ if (intfmacsel == DEVSTAT_MACSEL_RGMII)
+ emac_clearbit_reg(EMAC_MACCONTROL, EMAC_B_RGMIIEN);
+ }
+ mod_timer(&emac_timer, jiffies + EMAC_TIMER_PERIOD);
+}
+#endif /* EMAC_TIMER_TICK_MDIO */
+
+static const char emac_driver_name[] = "EMAC";
+
+static const struct net_device_ops gemac_netdev_ops = {
+ .ndo_open = emac_open,
+ .ndo_stop = emac_close,
+ .ndo_start_xmit = emac_start_xmit,
+ .ndo_tx_timeout = emac_timeout,
+ .ndo_set_multicast_list = emac_set_rx_mode,
+ .ndo_set_mac_address = eth_mac_addr,
+ .ndo_get_stats = emac_get_stats,
+#ifdef CONFIG_NET_POLL_CONTROLLER
+ .ndo_poll_controller = emac_poll,
+#endif
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_validate_addr = eth_validate_addr,
+};
+
+static const struct ethtool_ops gemac_ethtool_ops = {
+};
+
+static int __init emac_probe(struct platform_device *pdev)
+{
+ struct net_device *netdev;
+ struct emac_private *ep;
+ int res = -EINVAL;
+ int i;
+#ifdef EMAC_ARCH_HAS_MAC_ADDR
+ char hw_emac_addr[6];
+#endif
+ struct resource *cur_res;
+ static int ndevs;
+ int irq = 0;
+
+ emac_idx = get_emac_idx();
+
+ if (ndevs >= EMAC_MAX_INSTANCE) {
+ printk(KERN_ERR "gemac: Invalid instance: %d (max=%d)\n",
+ ndevs, EMAC_MAX_INSTANCE);
+ return -EINVAL;
+ }
+
+ /* Allocate private information */
+ netdev = alloc_etherdev(sizeof(struct emac_private));
+ if (!netdev)
+ return -ENOMEM;
+
+ SET_NETDEV_DEV(netdev, &pdev->dev);
+
+ ep = netdev_priv(netdev);
+ ep->dev = netdev;
+
+ spin_lock_init(&ep->lock);
+
+ /* Get irqs numbers */
+ cur_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "IRQ_SRC");
+ if (cur_res)
+ irq = cur_res->start;
+
+ /* Get EMAC I/O addresses */
+ ep->emac_reg_base = 0;
+ ep->ectl_reg_base = 0;
+ ep->emac_dsc_base = 0;
+ ep->mdio_reg_base = 0;
+
+ cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "EMAC_REG_BASE");
+ if (cur_res)
+ ep->emac_reg_base = cur_res->start;
+
+ cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "ECTL_REG_BASE");
+ if (cur_res)
+ ep->ectl_reg_base = cur_res->start;
+
+ cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "EMAC_DSC_BASE");
+ if (cur_res)
+ ep->emac_dsc_base = cur_res->start
+ + ((IDX_TO_CHAN(emac_idx) * QUEUE_DESC_NUM) << 4);
+
+#ifdef EMAC_DO_INIT_MDIO
+ cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+ "MDIO_REG_BASE");
+ if (cur_res)
+ ep->mdio_reg_base = cur_res->start;
+#endif
+
+ if (!irq || !ep->emac_reg_base || !ep->ectl_reg_base || !ep->emac_dsc_base) {
+ printk(KERN_ERR "%s: Unable to get hardware resources\n",
+ netdev->name);
+ goto error;
+ }
+
+ ep->mode_flags = config.flags;
+
+ if (emac_check_shared_capability())
+ ep->slave = emac_shared;
+
+ netdev->base_addr = ep->emac_reg_base;
+ netdev->dev_id = pdev->id;
+
+#ifdef EMAC_ARCH_HAS_MAC_ADDR
+ /* SoC or board hw has MAC address */
+ if (config.enetaddr[0] == 0 && config.enetaddr[1] == 0 &&
+ config.enetaddr[2] == 0 && config.enetaddr[3] == 0 &&
+ config.enetaddr[4] == 0 && config.enetaddr[5] == 0) {
+ if (!emac_arch_get_mac_addr(hw_emac_addr))
+ for (i = 0; i <= 5; i++)
+ config.enetaddr[i] = hw_emac_addr[i] & 0xff;
+ }
+#endif
+ /* Setup the device */
+ res = emac_reset(netdev, GEMAC_RESET_COLD);
+ if (res) {
+ free_netdev(netdev);
+ goto error;
+ }
+
+ /* driver system function */
+ ether_setup(netdev);
+
+ /* Set generic Ethernet operations */
+ netdev->netdev_ops = &gemac_netdev_ops;
+ netdev->watchdog_timeo = TX_TIMEOUT;
+ netdev->ethtool_ops = &gemac_ethtool_ops;
+
+ platform_set_drvdata(pdev, netdev);
+
+ /* Register Ethernet device */
+ res = register_netdev(netdev);
+ if (res) {
+ printk(KERN_ERR "%s: Unable to register netdev\n",
+ netdev->name);
+ goto error;
+ }
+
+ /* Setup transmit/receive buffers */
+ res = emac_setup_ring(ep);
+ if (res) {
+ printk(KERN_ERR "%s: Unable to allocate memory\n",
+ netdev->name);
+ goto error;
+ }
+
+#ifdef EMAC_TIMER_TICK_MDIO
+ /* Set EMAC timer */
+ init_timer(&emac_timer);
+ emac_timer.function = emac_timer_tick;
+ emac_timer.data = (unsigned long)netdev;
+ mod_timer(&emac_timer, jiffies + EMAC_TIMER_PERIOD);
+#endif
+
+ /* Install our interrupt handler(s) */
+#ifdef EMAC_HAS_SEPARATE_RXTX_IRQS
+ if ((request_irq(irq, emac_rx_interrupt, _INTFLAG, "GEMAC RX", netdev) == 0) &&
+ (request_irq(irq + 1, emac_tx_interrupt, _INTFLAG, "GEMAC TX", netdev) == 0))
+ netdev->irq = irq;
+#else
+ if (request_irq(irq, emac_interrupt, 0, "GEMAC", netdev) == 0)
+ netdev->irq = irq;
+#endif
+
+ printk(KERN_INFO "%s: EMAC(%d) driver version 2.1 IRQ=%d queue=%d %s",
+ netdev->name, pdev->id, netdev->irq, IDX_TO_CHAN(emac_idx),
+ emac_shared ? "shared\n" : "\n");
+
+ printk(KERN_INFO "%s: MAC address=", netdev->name);
+ for (i = 0; i < 5; i++)
+ printk(KERN_CONT "%02x:", netdev->dev_addr[i]);
+#ifdef CONFIG_SGMII
+ printk(KERN_CONT "%02x PHY=SGMII\n", netdev->dev_addr[i]);
+#else
+ printk(KERN_CONT "%02x PHY=%s%sMII\n", netdev->dev_addr[i],
+ ((mdio_get_macsel() & DEVSTAT_MACSEL_RMII) ? "R" : ""),
+ ((mdio_get_macsel() & DEVSTAT_MACSEL_GMII) ? "G" : ""));
+#endif
+ ++ndevs;
+ return 0;
+
+ error:
+ free_netdev(netdev);
+ return res;
+}
+
+static struct platform_driver emac_driver = {
+ .driver = {
+ .name = (char *) emac_driver_name,
+ .owner = THIS_MODULE,
+ },
+ .probe = emac_probe,
+};
+
+static void __exit emac_cleanup(void)
+{
+ platform_driver_unregister(&emac_driver);
+}
+module_exit(emac_cleanup);
+
+/*
+ * Initialize GEMAC controller
+ */
+static int emac_init(void)
+{
+ return platform_driver_register(&emac_driver);
+}
+
+module_init(emac_init);
+
diff --git a/drivers/net/c6x_gmdio.c b/drivers/net/c6x_gmdio.c
new file mode 100644
index 0000000..6a82519
--- /dev/null
+++ b/drivers/net/c6x_gmdio.c
@@ -0,0 +1,514 @@
+/*
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Nicolas Videau ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/init.h>
+#include <linux/spinlock.h>
+#include <linux/io.h>
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/gmdio.h>
+#include <asm/pll.h>
+
+static struct mdio_status mdios;
+
+/*
+ * Tick counts for timeout of each state
+ * Note that NWAYSTART falls through to NWAYWAIT which falls through
+ * to LINKWAIT. The timeout is not reset progressing from one state
+ * to the next, so the system has 5 seconds total to find a link.
+ */
+static unsigned int phy_timeout[] = { 2, /* MDIO_PHY_MDIOINIT - min-delay */
+ 6, /* MDIO_PHY_RESET - .5 sec max */
+ 41, /* MDIO_PHY_NWAYSTART - 4 seconds */
+ 41, /* MDIO_PHY_NWAYWAIT - 4 seconds */
+ 51, /* MDIO_PHY_LINKWAIT - 5 seconds */
+ 0 };/* MDIO_PHY_LINKED - no timeout */
+
+static void mdio_init_state_machine(void)
+{
+ mdios.phy_addr = 0;
+ mdios.phy_state = MDIO_PHY_MDIOINIT;
+ mdios.phy_ticks = 0;
+ mdios.link_status = MDIO_LINKSTATUS_NOLINK;
+}
+
+/*
+ * Initialize the MDIO
+ */
+int mdio_init(unsigned int txid_version)
+{
+#ifdef CONFIG_SOC_TMS320C6455
+ /* Get MAC interface */
+ mdios.macsel = (DSCR_DEVSTAT >> DEVSTAT_MACSEL_OFFSET) &
+ DEVSTAT_MACSEL_MASK;
+#else
+ /* Default (no gigabit support) */
+ mdios.macsel = DEVSTAT_MACSEL_MII;
+#endif
+
+ /* Get Transmit identification and version */
+ mdios.emac_txidver = txid_version;
+
+ mdios.mode = MDIO_MODE_AUTONEG; /* autonegotiate */
+ mdio_init_state_machine();
+ mdio_set_reg(MDIO_CONTROL, EMAC_B_ENABLE | (VBUSCLK & EMAC_M_CLKDIV));
+ return 0;
+}
+
+/*
+ * Return the current MDIO/PHY status
+ */
+unsigned int mdio_get_status(void)
+{
+ return mdios.link_status;
+}
+
+/*
+ * Return the current MDIO/PHY interface
+ */
+unsigned int mdio_get_macsel(void)
+{
+ mdios.macsel = (DSCR_DEVSTAT >> DEVSTAT_MACSEL_OFFSET) &
+ DEVSTAT_MACSEL_MASK;
+
+ return mdios.macsel;
+}
+
+/*
+ * Force a switch to the specified PHY, and start the negotiation process
+ */
+static unsigned int mdio_init_phy_1(volatile unsigned int phy_addr)
+{
+ unsigned short val, ack;
+ unsigned int lval;
+ unsigned int i;
+
+ mdios.phy_addr = phy_addr;
+ mdios.link_status = MDIO_LINKSTATUS_NOLINK;
+
+ /* Shutdown all other PHYs */
+ lval = mdio_get_reg(MDIO_ALIVE);
+ for (i = 0; lval; i++, lval >>= 1)
+ if ((lval & 1) && (i != phy_addr)) {
+ mdio_phy_write(MDIO_PHY_REG_CONTROL,
+ i,
+ (MDIO_PHY_B_ISOLATE |
+ MDIO_PHY_B_POWERDOWN));
+ mdio_phy_wait();
+ }
+
+#ifdef CONFIG_ARCH_BOARD_DSK6455
+ /* Settings for Broadcom phys */
+ if (mdios.macsel == DEVSTAT_MACSEL_RGMII) {
+ /* Put phy in copper mode */
+ mdio_phy_write(MDIO_PHY_REG_ACCESS, phy_addr,
+ MDIO_PHY_B_COPPER);
+ mdio_phy_wait_res_ack(val, ack);
+
+ /* If the PHY did not ACK the write, return zero */
+ if (!ack)
+ return 0;
+
+ mdio_phy_write(0x10, phy_addr, 0x0000);
+ mdio_phy_wait();
+
+ /* Put phy in RGMII mode/in-band status data for PG 2.0 */
+ if (mdios.emac_txidver != 0x000C1207) {
+ mdio_phy_write(MDIO_PHY_REG_SHADOW, phy_addr,
+ MDIO_PHY_B_INBAND);
+ mdio_phy_wait_res_ack(val, ack);
+
+ /* If the PHY did not ACK the write, return zero */
+ if (!ack)
+ return 0;
+ }
+
+ /* Patch for (older) board revB with R822 soldered */
+ mdio_phy_write(MDIO_PHY_REG_ACCESS, phy_addr, 0x8C00);
+ mdio_phy_wait_res_ack(val, ack);
+ /* End of patch */
+ }
+#endif
+
+ if (mdios.macsel == DEVSTAT_MACSEL_GMII) {
+ /* Put phy in copper mode */
+ mdio_phy_write(MDIO_PHY_REG_ACCESS, phy_addr,
+ MDIO_PHY_B_COPPER);
+ mdio_phy_wait_res_ack(val, ack);
+
+ /* If the PHY did not ACK the write, return zero */
+ if (!ack)
+ return 0;
+ }
+
+ /* Ready for next init step */
+ mdios.phy_state = MDIO_PHY_RESET;
+ mdios.phy_ticks = 0;
+
+ return 1;
+}
+
+static unsigned int mdio_init_phy_2(volatile unsigned int phy_addr)
+{
+ unsigned short val, val2, valgig = 0;
+
+ mdios.phy_addr = phy_addr;
+
+ /* Read the STATUS reg to check autonegotiation capability */
+ mdio_phy_read(MDIO_PHY_REG_STATUS, phy_addr);
+ mdio_phy_wait_res(val);
+
+ if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
+ (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
+ mdio_phy_read(MDIO_PHY_REG_EXTSTATUS, phy_addr);
+ mdio_phy_wait_res(valgig);
+ }
+
+ /* See if we auto-neg or not */
+ if ((mdios.mode & MDIO_MODE_AUTONEG) &&
+ (val & MDIO_PHY_B_AUTOCAPABLE)) {
+ /* We will use NWAY */
+
+ /* Advertise 1000 for supported interfaces */
+ if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
+ (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
+ valgig >>= 4;
+ valgig &= MDIO_PHY_ADV_FD1000;
+
+ mdio_phy_write(MDIO_PHY_REG_1000CONTROL, phy_addr,
+ valgig);
+ mdio_phy_wait();
+ }
+
+ /* Shift down the capability bits */
+ val >>= 6;
+
+ /* Mask with the capabilities */
+ val &= (MDIO_PHY_B_AFD100 | MDIO_PHY_B_AHD100 |
+ MDIO_PHY_B_AFD10 | MDIO_PHY_B_AHD10);
+
+ /* Set Ethernet message bit */
+ val |= MDIO_PHY_B_MSG;
+
+ /* Write out advertisement */
+ mdio_phy_write(MDIO_PHY_REG_ADVERTISE, phy_addr, val);
+ mdio_phy_wait();
+
+ /* Start NWAY */
+ mdio_phy_write(MDIO_PHY_REG_CONTROL,
+ phy_addr,
+ MDIO_PHY_B_AUTONEGEN);
+ mdio_phy_wait();
+
+ mdio_phy_write(MDIO_PHY_REG_CONTROL,
+ phy_addr,
+ (MDIO_PHY_B_AUTONEGEN | MDIO_PHY_B_AUTORESTART));
+ mdio_phy_wait();
+
+ /* Setup current state */
+ mdios.mode |= MDIO_MODE_NWAYACTIVE;
+ mdios.phy_state = MDIO_PHY_NWAYSTART;
+ mdios.phy_ticks = 0;
+
+ } else {
+ /* Otherwise use a fixed configuration */
+
+ /* Shift down the capability bits */
+ val >>= 10;
+
+ /* Mask with possible modes */
+ val &= (MDIO_MODE_HD10 | MDIO_MODE_FD10 |
+ MDIO_MODE_HD100 | MDIO_MODE_FD100);
+
+ if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
+ (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
+ valgig >>= 8;
+ valgig &= MDIO_MODE_FD1000;
+
+ valgig &= mdios.mode;
+ }
+
+ /* Mask with what the User wants to allow */
+ val &= mdios.mode;
+
+ /* If nothing if left, move on */
+ if ((!val) && (!valgig))
+ return 0;
+
+ /* Setup Control word and pending status */
+ if (valgig) {
+ val2 = MDIO_PHY_B_SPEEDMSB | MDIO_PHY_B_DUPLEXFULL;
+ mdios.pending_status = MDIO_LINKSTATUS_FD1000;
+ } else if (val & MDIO_MODE_FD100) {
+ val2 = MDIO_PHY_B_SPEEDLSB | MDIO_PHY_B_DUPLEXFULL;
+ mdios.pending_status = MDIO_LINKSTATUS_FD100;
+ } else if (val & MDIO_MODE_HD100) {
+ val2 = MDIO_PHY_B_SPEEDLSB;
+ mdios.pending_status = MDIO_LINKSTATUS_HD100;
+ } else if (val & MDIO_MODE_FD10) {
+ val2 = MDIO_PHY_B_DUPLEXFULL;
+ mdios.pending_status = MDIO_PHY_B_FD10;
+ } else {
+ val2 = 0;
+ mdios.pending_status = MDIO_LINKSTATUS_HD10;
+ }
+
+ /* Add in loopback if user wanted it */
+ if (mdios.mode & MDIO_MODE_LOOPBACK)
+ val2 |= MDIO_PHY_B_LOOPBACK;
+
+ /* Configure PHY */
+ mdio_phy_write(MDIO_PHY_REG_CONTROL, phy_addr,
+ (val2 | MDIO_PHY_B_AUTORESTART));
+ mdio_phy_wait();
+
+ /* Add in external loopback with plug if user wanted it */
+ if (mdios.mode & MDIO_MODE_EXTLOOPBACK) {
+ mdio_phy_write(MDIO_PHY_REG_SHADOW, phy_addr,
+ MDIO_PHY_B_EXTLOOPBACK);
+ mdio_phy_wait();
+ }
+
+ /* Setup current state */
+ mdios.mode &= ~MDIO_MODE_NWAYACTIVE;
+ mdios.phy_state = MDIO_PHY_LINKWAIT;
+ mdios.phy_ticks = 0;
+ }
+ return 1;
+}
+
+
+/*
+ * Called each 100mS to check if MDIO status has changed.
+ * A MDIO event is returned.
+ */
+unsigned int mdio_timer_tick(void)
+{
+ unsigned int res = MDIO_EVENT_NOCHANGE;
+ unsigned short val, val2, valgig = 0, valgig2 = 0, ack;
+ unsigned int lval;
+
+ if (mdios.phy_state == MDIO_PHY_LINKED) {
+ /*
+ * Check for a "link-change" status indication or a link
+ * down indication.
+ */
+ lval = mdio_get_reg(MDIO_LINKINTRAW) & 1;
+ mdio_set_reg(MDIO_LINKINTRAW, lval);
+ if (lval || !(mdio_get_reg(MDIO_LINK) & (1 << mdios.phy_addr))) {
+
+ mdios.link_status = MDIO_LINKSTATUS_NOLINK;
+ mdios.phy_ticks = 0;
+ res = MDIO_EVENT_LINKDOWN;
+
+ /* If not NWAY, just wait for link */
+ if (!(mdios.mode & MDIO_MODE_NWAYACTIVE))
+ mdios.phy_state = MDIO_PHY_LINKWAIT;
+ else {
+ /* Handle NWAY condition */
+ mdio_phy_read(MDIO_PHY_REG_STATUS,
+ mdios.phy_addr);
+ mdio_phy_wait();
+ mdio_phy_read(MDIO_PHY_REG_STATUS,
+ mdios.phy_addr);
+ mdio_phy_wait_res_ack(val, ack);
+ if (!ack)
+ mdio_init_state_machine();
+
+ else if (!(val & MDIO_PHY_B_LINKSTATUS)) {
+ /* No Link - restart NWAY */
+ mdios.phy_state = MDIO_PHY_NWAYSTART;
+
+ mdio_phy_write(MDIO_PHY_REG_CONTROL,
+ mdios.phy_addr,
+ (MDIO_PHY_B_AUTONEGEN |
+ MDIO_PHY_B_AUTORESTART));
+ mdio_phy_wait();
+ } else
+ /* We have a Link - re-read NWAY params */
+ mdios.phy_state = MDIO_PHY_NWAYWAIT;
+ }
+ }
+ }
+
+ if (mdios.phy_state != MDIO_PHY_LINKED) {
+ /* Bump the time counter */
+ mdios.phy_ticks++;
+
+ /* Process differently based on state */
+ switch (mdios.phy_state) {
+#if !(defined(CONFIG_SOC_TMS3206472) || defined(CONFIG_SOC_TMS3206474)) && \
+ !defined(CONFIG_SOC_TMS3206457)
+ case MDIO_PHY_RESET:
+ /* Don't read reset status for the first 100 to 200 ms */
+ if (mdios.phy_ticks < 2)
+ break;
+
+ /* See if the PHY has come out of reset */
+ mdio_phy_read(MDIO_PHY_REG_CONTROL,
+ mdios.phy_addr);
+ mdio_phy_wait_res_ack(val, ack);
+
+ if (ack && !(val & MDIO_PHY_B_RESET)) {
+ /* PHY is not reset.
+ * If the PHY init is going well, break out */
+ if (mdio_init_phy_2(mdios.phy_addr))
+ break;
+ /* Else, this PHY is toast.
+ * Manually trigger a timeout */
+ mdios.phy_ticks = phy_timeout[mdios.phy_state];
+ }
+
+ /* Fall through to timeout check */
+#endif
+ case MDIO_PHY_MDIOINIT:
+ check_timeout:
+ /* Here we just check timeout and try to find a PHY */
+ if (mdios.phy_ticks >= phy_timeout[mdios.phy_state]) {
+ /* Try the next PHY if anything but
+ * a MDIOINIT condition */
+ if (mdios.phy_state != MDIO_PHY_MDIOINIT)
+ if (++mdios.phy_addr == 32)
+ mdios.phy_addr = 0;
+
+ lval = mdio_get_reg(MDIO_ALIVE);
+
+ for (val = 0; val < 32; val++) {
+
+ if ((lval & (1 << mdios.phy_addr)) &&
+ (mdio_init_phy_1(mdios.phy_addr)))
+ break;
+
+ if (++mdios.phy_addr == 32)
+ mdios.phy_addr = 0;
+ }
+
+ /* If we didn't find a PHY, try again */
+ if (val == 32) {
+ mdios.phy_addr = 0;
+ mdios.phy_state = MDIO_PHY_MDIOINIT;
+ mdios.phy_ticks = 0;
+ res = MDIO_EVENT_PHYERROR;
+ }
+ }
+ break;
+
+ case MDIO_PHY_NWAYSTART:
+ /* Start NWAY */
+
+ /* Read the CONTROL reg to verify "restart" is not set */
+ mdio_phy_read(MDIO_PHY_REG_CONTROL, mdios.phy_addr);
+ mdio_phy_wait_res_ack(val, ack);
+ if (!ack) {
+ mdio_init_state_machine();
+ break;
+ }
+
+ if (val & MDIO_PHY_B_AUTORESTART)
+ goto check_timeout;
+
+ /* Flush latched "link status" from the STATUS reg */
+ mdio_phy_read(MDIO_PHY_REG_STATUS, mdios.phy_addr);
+ mdio_phy_wait();
+
+ mdios.phy_state = MDIO_PHY_NWAYWAIT;
+
+ /* Fallthrough */
+
+ case MDIO_PHY_NWAYWAIT:
+ /* Waiting NWAY to complete */
+
+ /* Read the STATUS reg to check for "complete" */
+ mdio_phy_read(MDIO_PHY_REG_STATUS, mdios.phy_addr);
+ mdio_phy_wait_res_ack(val, ack);
+ if (!ack) {
+ mdio_init_state_machine();
+ break;
+ }
+
+ if (!(val & MDIO_PHY_B_AUTOCOMPLETE))
+ goto check_timeout;
+#if !(defined(CONFIG_SOC_TMS3206472) || defined(CONFIG_SOC_TMS3206474)) && !defined(CONFIG_SOC_TMS3206457)
+ /* We can now check the negotiation results */
+ if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
+ (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
+ mdio_phy_read(MDIO_PHY_REG_1000CONTROL,
+ mdios.phy_addr);
+ mdio_phy_wait_res(valgig);
+ mdio_phy_read(MDIO_PHY_REG_1000STATUS,
+ mdios.phy_addr);
+ mdio_phy_wait_res(valgig2);
+ }
+#endif
+ mdio_phy_read(MDIO_PHY_REG_ADVERTISE, mdios.phy_addr);
+ mdio_phy_wait_res(val);
+ mdio_phy_read(MDIO_PHY_REG_PARTNER, mdios.phy_addr);
+ mdio_phy_wait_res(val2);
+
+ val2 &= val;
+#if !(defined(CONFIG_SOC_TMS3206472) || defined(CONFIG_SOC_TMS3206474)) && !defined(CONFIG_SOC_TMS3206457)
+ if ((valgig & MDIO_PHY_ADV_FD1000) &&
+ (valgig2 & MDIO_PHY_PRT_FD1000))
+ mdios.pending_status = MDIO_LINKSTATUS_FD1000;
+ else if (val2 & MDIO_PHY_B_AFD100)
+ mdios.pending_status = MDIO_LINKSTATUS_FD100;
+#else
+ if (val2 & MDIO_PHY_B_AFD100)
+ mdios.pending_status = MDIO_LINKSTATUS_FD100;
+#endif
+ else if (val2 & MDIO_PHY_B_AHD100)
+ mdios.pending_status = MDIO_LINKSTATUS_HD100;
+ else if (val2 & MDIO_PHY_B_AFD10)
+ mdios.pending_status = MDIO_LINKSTATUS_FD10;
+ else if (val2 & MDIO_PHY_B_AHD10)
+ mdios.pending_status = MDIO_LINKSTATUS_HD10;
+ else if (val & MDIO_PHY_B_AHD100)
+ mdios.pending_status = MDIO_LINKSTATUS_HD100;
+ else
+ mdios.pending_status = MDIO_LINKSTATUS_HD10;
+
+ mdios.phy_state = MDIO_PHY_LINKWAIT;
+
+ case MDIO_PHY_LINKWAIT:
+ /* Waiting for LINK */
+ mdio_phy_read(MDIO_PHY_REG_STATUS, mdios.phy_addr);
+ mdio_phy_wait_res_ack(val, ack);
+ if (!ack) {
+ mdio_init_state_machine();
+ break;
+ }
+
+ if (!(val & MDIO_PHY_B_LINKSTATUS))
+ goto check_timeout;
+
+ /* Make sure we're linked in the MDIO module as well */
+ lval = mdio_get_reg(MDIO_LINK);
+ if (!(lval & (1 << mdios.phy_addr)))
+ goto check_timeout;
+
+ /* Start monitoring this PHY */
+ mdio_set_reg(MDIO_USERPHYSEL0, mdios.phy_addr);
+
+ /* Clear the link change flag so we can detect a "re-link" later */
+ mdio_set_reg(MDIO_LINKINTRAW, 1);
+
+ /* Setup our linked state */
+ mdios.phy_state = MDIO_PHY_LINKED;
+ mdios.link_status = mdios.pending_status;
+ res = MDIO_EVENT_LINKUP;
+ break;
+ }
+ }
+ return res;
+}
--
1.6.2.5

2011-05-11 21:10:42

by Mark Salter

[permalink] [raw]
Subject: [PATCH 04/16] add support for C64x+ debugger based console

Texas Instruments debugger support for the C64X+ family of DSPs includes a
console for the unit under test. This patch adds write-only console support
to send kernel output to the debugger. It is safe to have this driver in
place even if the system is not being run under the debugger.

Signed-off-by: Mark Salter <[email protected]>
---
drivers/tty/hvc/Makefile | 1 +
drivers/tty/hvc/hvc_c6x.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 126 insertions(+), 0 deletions(-)
create mode 100644 drivers/tty/hvc/hvc_c6x.c

diff --git a/drivers/tty/hvc/Makefile b/drivers/tty/hvc/Makefile
index 40a25d9..02e08cb 100644
--- a/drivers/tty/hvc/Makefile
+++ b/drivers/tty/hvc/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_HVC_IUCV) += hvc_iucv.o
obj-$(CONFIG_HVC_UDBG) += hvc_udbg.o
obj-$(CONFIG_HVC_BFIN_JTAG) += hvc_bfin_jtag.o
obj-$(CONFIG_HVCS) += hvcs.o
+obj-$(CONFIG_HVC_C6X) += hvc_c6x.o
diff --git a/drivers/tty/hvc/hvc_c6x.c b/drivers/tty/hvc/hvc_c6x.c
new file mode 100644
index 0000000..54ea20b
--- /dev/null
+++ b/drivers/tty/hvc/hvc_c6x.c
@@ -0,0 +1,125 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * Based on hvc_tile.c
+ * Copyright 2010 Tilera Corporation. All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+
+/*
+ * TI C6X Host Port hypervisor console
+ */
+
+#include <linux/console.h>
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/init.h>
+#include <linux/moduleparam.h>
+#include <linux/types.h>
+
+#include "hvc_console.h"
+
+#define PARAMSIZE 8
+#define MSGSIZE 256
+
+#define CIO_READ 0xF2
+#define CIO_WRITE 0xF3
+
+#define CIO_STDIN 0
+#define CIO_STDOUT 1
+#define CIO_STDERR 2
+
+struct c6x_msg {
+ unsigned int length;
+ unsigned char command;
+ unsigned char params[PARAMSIZE];
+ unsigned char msg[MSGSIZE];
+};
+
+union c6x_msgparam {
+ unsigned char params[PARAMSIZE];
+ struct {
+ unsigned short fd;
+ unsigned short count;
+ } host_write;
+};
+
+/*
+ * __CIOBUF__ and C$$IO$$ are special symbols for debugger.
+ *
+ * If debugger is running kernel, it will set a breakpoint
+ * at C$$IO$$ which is hit when the kernel wants attention
+ * from the debugger. __CIOBUF__ is used to pass messages
+ * between debugger and kernel when the breakpoint is hit.
+ */
+struct c6x_msg _CIOBUF_;
+
+static noinline void notify_debugger(void)
+{
+ asm volatile (".global C$$IO$$\n"
+ "nop\n"
+ "C$$IO$$: nop\n");
+}
+
+static int hvc_c6x_put_chars(uint32_t vt, const char *buf, int count)
+{
+ union c6x_msgparam params;
+ int to_write, remaining;
+
+ remaining = count;
+ while (remaining > 0) {
+ to_write = (remaining > MSGSIZE) ? MSGSIZE : remaining;
+
+ _CIOBUF_.length = to_write;
+ _CIOBUF_.command = CIO_WRITE;
+
+ params.host_write.fd = cpu_to_le16(CIO_STDOUT);
+ params.host_write.count = cpu_to_le16(to_write);
+ memcpy(_CIOBUF_.params, &params, PARAMSIZE);
+
+ memcpy(_CIOBUF_.msg, buf, to_write);
+
+ notify_debugger();
+
+ remaining -= to_write;
+ }
+ return count;
+}
+
+#ifdef CONFIG_EARLY_PRINTK
+void hvc_c6x_early_puts(const char *buf, unsigned count)
+{
+ hvc_c6x_put_chars(0, buf, count);
+}
+#endif
+
+static int hvc_c6x_get_chars(uint32_t vt, char *buf, int count)
+{
+ return 0;
+}
+
+static const struct hv_ops hvc_c6x_get_put_ops = {
+ .get_chars = hvc_c6x_get_chars,
+ .put_chars = hvc_c6x_put_chars,
+};
+
+static int __init hvc_c6x_console_init(void)
+{
+ hvc_instantiate(0, 0, &hvc_c6x_get_put_ops);
+ add_preferred_console("hvc", 0, NULL);
+ return 0;
+}
+console_initcall(hvc_c6x_console_init);
+
+static int __init hvc_c6x_init(void)
+{
+ struct hvc_struct *s;
+ s = hvc_alloc(0, 0, &hvc_c6x_get_put_ops, 128);
+ return IS_ERR(s) ? PTR_ERR(s) : 0;
+}
+device_initcall(hvc_c6x_init);
--
1.6.2.5

2011-05-12 02:41:53

by Milton Miller

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux


On Wed, 11 May 2011 around 17:11:19 EST, Mark Salter wrote:
> This patch series adds support for a new architecture (arch/c6x) to
> Linux. This architecture supports members of the Texas Instruments
> family of C64x single and multicore DSPs. The multicore DSPs do not
> support cache coherancy, so are not suitable for SMP. Also, these are
> no-mmu processors. This core architecture is VLIW with an instruction
> set optimized for DSP applications. For details on the processors:

So all the changelogs talk about C64x but the arch and all the configs
are called c6x? Is it that hard to type 2 digits? Or do you expect
an additional chip that breaks the C64 but would fit the C6x name?


Also, a couple of one liners while preparing my comments on hvc_c6x:

[09/16] C6X: add kernel files

in kernel/setup.c you include linux/delay.h multiple times



[11/16] C6X: add lib files

arch/c6x/lib/memset.c

(1) file header says linux/arch/c6x/lib/memcmp.c
(you should probably just delete such headers, they are just maintence errors)

(2) it appears to mach lib/string.c implementation except (1) register (2)
uses post-increment instead of pre-increment. Does it matter with gcc?

arch/c6x/lib/memcmp.c
your version returns -1 or 1 while string.c returns the difference
after promotion to int. man page for userspace says just integer less
than or greater, so I guess this is ok. But is this more efficient,
or could you use the generic version?


milton

2011-05-11 21:06:40

by Mark Salter

[permalink] [raw]
Subject: [PATCH 05/16] add ELF machine define for TI C6X DSPs

Signed-off-by: Mark Salter <[email protected]>
---
include/linux/elf-em.h | 1 +
1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/include/linux/elf-em.h b/include/linux/elf-em.h
index 18bea78..8e2b7ba 100644
--- a/include/linux/elf-em.h
+++ b/include/linux/elf-em.h
@@ -33,6 +33,7 @@
#define EM_H8_300 46 /* Renesas H8/300,300H,H8S */
#define EM_MN10300 89 /* Panasonic/MEI MN10300, AM33 */
#define EM_BLACKFIN 106 /* ADI Blackfin Processor */
+#define EM_TI_C6000 140 /* TI C6X DSPs */
#define EM_FRV 0x5441 /* Fujitsu FR-V */
#define EM_AVR32 0x18ad /* Atmel AVR32 */

--
1.6.2.5

2011-05-11 21:06:42

by Mark Salter

[permalink] [raw]
Subject: [PATCH 06/16] add maintainers entry for C6X arch

Signed-off-by: Mark Salter <[email protected]>
---
MAINTAINERS | 11 +++++++++++
1 files changed, 11 insertions(+), 0 deletions(-)

diff --git a/MAINTAINERS b/MAINTAINERS
index 16a5c5f..4da0c6d 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1601,6 +1601,17 @@ T: git git://git.alsa-project.org/alsa-kernel.git
S: Maintained
F: sound/pci/oxygen/

+C6X ARCHITECTURE
+M: Mark Salter <[email protected]>
+M: Aurelien Jacquiot <[email protected]>
+L: [email protected]
+W: http://www.linux-c6x.org/wiki/index.php/Main_Page
+S: Maintained
+F: arch/c6x/
+F: drivers/net/c6x_*
+F: drivers/platforms/c6x/
+F: drivers/tty/hvc/hvc_c6x.c
+
CACHEFILES: FS-CACHE BACKEND FOR CACHING ON MOUNTED FILESYSTEMS
M: David Howells <[email protected]>
L: [email protected]
--
1.6.2.5

2011-05-11 21:10:16

by Mark Salter

[permalink] [raw]
Subject: [PATCH 07/16] C6X: add toplevel configury and makefile

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/Kconfig | 213 ++++++++++++++++++++++++++++++++++++++++++++++++
arch/c6x/Kconfig.debug | 25 ++++++
arch/c6x/Makefile | 33 ++++++++
3 files changed, 271 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/Kconfig
create mode 100644 arch/c6x/Kconfig.debug
create mode 100644 arch/c6x/Makefile

diff --git a/arch/c6x/Kconfig b/arch/c6x/Kconfig
new file mode 100644
index 0000000..d4881c1
--- /dev/null
+++ b/arch/c6x/Kconfig
@@ -0,0 +1,213 @@
+#
+# For a description of the syntax of this configuration file,
+# see Documentation/kbuild/kconfig-language.txt.
+#
+
+config TMS320C6X
+ def_bool y
+ select GENERIC_IRQ_SHOW
+ select HAVE_GENERIC_HARDIRQS
+ select GENERIC_FIND_FIRST_BIT
+ select GENERIC_FIND_NEXT_BIT
+ select GENERIC_FIND_LAST_BIT
+ select GENERIC_FIND_BIT_LE
+
+config MMU
+ def_bool n
+
+config ZONE_DMA
+ def_bool y
+
+config SBUS
+ def_bool n
+
+config FPU
+ def_bool n
+
+config HIGHMEM
+ def_bool n
+
+config NUMA
+ def_bool n
+
+config RWSEM_GENERIC_SPINLOCK
+ def_bool y
+
+config RWSEM_XCHGADD_ALGORITHM
+ def_bool n
+
+config GENERIC_CALIBRATE_DELAY
+ def_bool y
+
+config GENERIC_FIND_NEXT_BIT
+ def_bool y
+
+config GENERIC_HWEIGHT
+ def_bool y
+
+config GENERIC_TIME
+ def_bool y
+
+config GENERIC_CLOCKEVENTS
+ def_bool y
+
+config GENERIC_CLOCKEVENTS_BUILD
+ def_bool y
+ depends on GENERIC_CLOCKEVENTS
+
+config GENERIC_CLOCKEVENTS_BROADCAST
+ bool
+
+config GENERIC_BUG
+ def_bool y
+
+config COMMON_CLKDEV
+ def_bool y
+
+config BIG_KERNEL
+ bool "Build a big kernel"
+ help
+ The C6X function call instruction has a limited range of +/- 2MiB.
+ This is sufficient for most kernels, but some kernel configurations
+ with lots of compiled-in functionality may require a larger range
+ for function calls. Use this option to have the compiler generate
+ function calls with 32-bit range. This will make the kernel both
+ larger and slower.
+
+ If unsure, say N.
+
+config XIP_KERNEL
+ bool "Kernel Execute-In-Place"
+ help
+ Execute-In-Place allows the kernel to run from non-volatile storage
+ directly addressable by the CPU, such as NOR flash. This saves RAM
+ space since the text section of the kernel is not loaded from flash
+ to RAM. Read-write sections, such as the data section and stack,
+ are still copied to RAM. The XIP kernel is not compressed since
+ it has to run directly from flash, so it will take more space to
+ store it. The flash address used to link the kernel object files,
+ and for storing it, is configuration dependent. Therefore, if you
+ say Y here, you must know the proper physical address where to
+ store the kernel image depending on your own flash memory usage.
+
+ If unsure, say N.
+
+config XIP_KERNEL_TEXT_ADDR
+ hex "XIP Kernel Physical Location"
+ depends on XIP_KERNEL
+ default "0xB0000000"
+ help
+ This is the physical address where the kernel image will be
+ stored. This address is dependent on your own platform
+ device constraints.
+
+source "init/Kconfig"
+
+# Use the generic interrupt handling code in kernel/irq/
+
+source "kernel/Kconfig.freezer"
+
+config CMDLINE
+ string "Kernel command line"
+ default "console=ttyS0,57600"
+
+config CPU_BIG_ENDIAN
+ bool "Build big-endian kernel"
+ help
+ Say Y if you plan on running a kernel in big-endian mode.
+ Note that your board must be properly built and your board
+ port must properly enable any big-endian related features
+ of your chipset/board/processor.
+
+config FORCE_MAX_ZONEORDER
+ int
+ default "13"
+
+menu "Processor type and features"
+
+config TMS320C64XPLUS
+ bool "TMS320C64X+"
+ select SERIAL_CORE
+
+config HVC_C6X
+ bool "HVC console (CIO)"
+ select HVC_DRIVER
+ def_bool y
+
+source "arch/c6x/platforms/Kconfig"
+
+config USE_RT_TIMER
+ bool "Compensate for lost ticks"
+ default n
+
+config SGMII
+ bool "Ethernet SGMII support"
+ default n
+
+config TMS320C64X_GEMAC_0
+ bool "First Ethernet interface"
+ depends on TMS320C64X_GEMAC && SOC_TMS320C6472
+ default y
+
+config TMS320C64X_GEMAC_1
+ bool "Second Ethernet interface"
+ depends on TMS320C64X_GEMAC && SOC_TMS320C6472
+ default n
+
+config TMS320C6X_CACHES_ON
+ bool "L2 cache support"
+ default y
+
+config KERNEL_RAM_BASE_ADDRESS
+ hex "Virtual address of memory base"
+ default 0xe0000000 if SOC_TMS320C6455
+ default 0xe0000000 if SOC_TMS320C6457
+ default 0xe0000000 if SOC_TMS320C6472
+ default 0x80000000
+
+source "mm/Kconfig"
+
+source "kernel/Kconfig.preempt"
+
+source "kernel/Kconfig.hz"
+source "kernel/time/Kconfig"
+
+endmenu
+
+menu "Bus options (PCI, PCMCIA, EISA, MCA, ISA)"
+
+config PCI
+ bool "PCI support"
+ help
+ Support for PCI bus.
+endmenu
+
+menu "Executable file formats"
+
+source "fs/Kconfig.binfmt"
+
+endmenu
+
+menu "Power management options"
+
+config PM
+ bool "Power Management support"
+ help
+ Support processor power management modes
+
+endmenu
+
+source "net/Kconfig"
+
+source "drivers/Kconfig"
+
+source "fs/Kconfig"
+
+source "security/Kconfig"
+
+source "crypto/Kconfig"
+
+source "lib/Kconfig"
+
+source "arch/c6x/Kconfig.debug"
+
diff --git a/arch/c6x/Kconfig.debug b/arch/c6x/Kconfig.debug
new file mode 100644
index 0000000..49b18b2
--- /dev/null
+++ b/arch/c6x/Kconfig.debug
@@ -0,0 +1,25 @@
+menu "Kernel hacking"
+
+source "lib/Kconfig.debug"
+
+config EARLY_PRINTK
+ bool "Early printk"
+ default n
+ help
+ This option enables special console drivers which allow the kernel
+ to print messages very early in the bootup process.
+
+ This is useful for kernel debugging when your machine crashes very
+ early before the console code is initialized. After enabling this
+ feature, you must add "earlyprintk=hvc" to the command line (bootargs).
+
+config ACCESS_CHECK
+ bool "Check the user pointer address"
+ default y
+ help
+ Usually the pointer transfer from user space is checked to see if its
+ address is in the kernel space.
+
+ Say N here to disable that check to improve the performance.
+
+endmenu
diff --git a/arch/c6x/Makefile b/arch/c6x/Makefile
new file mode 100644
index 0000000..3561875
--- /dev/null
+++ b/arch/c6x/Makefile
@@ -0,0 +1,33 @@
+#
+# linux/arch/c6x/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.
+#
+
+cflags-y := -D__linux__ -D__TMS320C6X__
+
+cflags-$(CONFIG_TMS320C64XPLUS) += -D__TMS320C6XPLUS__ -march=c64x+ -msdata=none -mno-dsbt
+
+cflags-$(CONFIG_BIG_KERNEL) += -mlong-calls
+
+CFLAGS_MODULE += -mlong-calls
+
+KBUILD_CPPFLAGS += -I$(srctree)/arch/c6x/platforms/include -I$(obj)/arch/c6x/kernel
+
+KBUILD_CFLAGS += $(cflags-y)
+KBUILD_AFLAGS += $(cflags-y)
+
+ifdef CONFIG_CPU_BIG_ENDIAN
+KBUILD_CFLAGS += -mbig-endian
+KBUILD_AFLAGS += -mbig-endian
+LINKFLAGS += -mbig-endian
+KBUILD_LDFLAGS += -mbig-endian
+LDFLAGS += -EB
+endif
+
+head-y := arch/c6x/kernel/head.o
+core-y += arch/c6x/kernel/ arch/c6x/mm/ arch/c6x/platforms/
+libs-y += arch/c6x/lib/
+
--
1.6.2.5

2011-05-11 21:07:21

by Mark Salter

[permalink] [raw]
Subject: [PATCH 08/16] C6X: add include files

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/include/asm/Kbuild | 2 +
arch/c6x/include/asm/asm-offsets.h | 1 +
arch/c6x/include/asm/atomic.h | 6 +
arch/c6x/include/asm/auxvec.h | 6 +
arch/c6x/include/asm/bitops.h | 181 +++++++++++++++
arch/c6x/include/asm/bitsperlong.h | 6 +
arch/c6x/include/asm/bug.h | 6 +
arch/c6x/include/asm/bugs.h | 6 +
arch/c6x/include/asm/byteorder.h | 12 +
arch/c6x/include/asm/cache.h | 373 ++++++++++++++++++++++++++++++
arch/c6x/include/asm/cacheflush.h | 67 ++++++
arch/c6x/include/asm/checksum.h | 116 +++++++++
arch/c6x/include/asm/clkdev.h | 45 ++++
arch/c6x/include/asm/clock.h | 73 ++++++
arch/c6x/include/asm/cputime.h | 6 +
arch/c6x/include/asm/current.h | 6 +
arch/c6x/include/asm/delay.h | 69 ++++++
arch/c6x/include/asm/device.h | 6 +
arch/c6x/include/asm/div64.h | 6 +
arch/c6x/include/asm/dma-mapping.h | 302 ++++++++++++++++++++++++
arch/c6x/include/asm/dma.h | 25 ++
arch/c6x/include/asm/elf.h | 115 +++++++++
arch/c6x/include/asm/emergency-restart.h | 6 +
arch/c6x/include/asm/errno.h | 6 +
arch/c6x/include/asm/fb.h | 6 +
arch/c6x/include/asm/fcntl.h | 6 +
arch/c6x/include/asm/ftrace.h | 6 +
arch/c6x/include/asm/futex.h | 6 +
arch/c6x/include/asm/gemac.h | 146 ++++++++++++
arch/c6x/include/asm/gmdio.h | 217 +++++++++++++++++
arch/c6x/include/asm/hardirq.h | 22 ++
arch/c6x/include/asm/hardware.h | 21 ++
arch/c6x/include/asm/hw_irq.h | 6 +
arch/c6x/include/asm/io.h | 6 +
arch/c6x/include/asm/ioctl.h | 6 +
arch/c6x/include/asm/ioctls.h | 6 +
arch/c6x/include/asm/ipcbuf.h | 6 +
arch/c6x/include/asm/irq.h | 101 ++++++++
arch/c6x/include/asm/irq_regs.h | 6 +
arch/c6x/include/asm/irqflags.h | 71 ++++++
arch/c6x/include/asm/kdebug.h | 6 +
arch/c6x/include/asm/kmap_types.h | 6 +
arch/c6x/include/asm/leds.h | 22 ++
arch/c6x/include/asm/linkage.h | 6 +
arch/c6x/include/asm/local.h | 6 +
arch/c6x/include/asm/mman.h | 7 +
arch/c6x/include/asm/mmu.h | 20 ++
arch/c6x/include/asm/mmu_context.h | 6 +
arch/c6x/include/asm/module.h | 35 +++
arch/c6x/include/asm/msgbuf.h | 6 +
arch/c6x/include/asm/mutex.h | 6 +
arch/c6x/include/asm/page.h | 11 +
arch/c6x/include/asm/param.h | 6 +
arch/c6x/include/asm/pci.h | 6 +
arch/c6x/include/asm/percpu.h | 6 +
arch/c6x/include/asm/pgalloc.h | 6 +
arch/c6x/include/asm/pgtable.h | 83 +++++++
arch/c6x/include/asm/pll.h | 79 +++++++
arch/c6x/include/asm/pm.h | 48 ++++
arch/c6x/include/asm/poll.h | 6 +
arch/c6x/include/asm/posix_types.h | 6 +
arch/c6x/include/asm/processor.h | 118 ++++++++++
arch/c6x/include/asm/procinfo.h | 30 +++
arch/c6x/include/asm/ptrace.h | 186 +++++++++++++++
arch/c6x/include/asm/resource.h | 6 +
arch/c6x/include/asm/scatterlist.h | 6 +
arch/c6x/include/asm/sections.h | 17 ++
arch/c6x/include/asm/segment.h | 1 +
arch/c6x/include/asm/sembuf.h | 6 +
arch/c6x/include/asm/serial.h | 25 ++
arch/c6x/include/asm/setup.h | 49 ++++
arch/c6x/include/asm/sgmii.h | 53 +++++
arch/c6x/include/asm/shmbuf.h | 6 +
arch/c6x/include/asm/shmparam.h | 6 +
arch/c6x/include/asm/sigcontext.h | 83 +++++++
arch/c6x/include/asm/siginfo.h | 6 +
arch/c6x/include/asm/signal.h | 17 ++
arch/c6x/include/asm/socket.h | 6 +
arch/c6x/include/asm/sockios.h | 6 +
arch/c6x/include/asm/stat.h | 6 +
arch/c6x/include/asm/statfs.h | 6 +
arch/c6x/include/asm/string.h | 29 +++
arch/c6x/include/asm/swab.h | 6 +
arch/c6x/include/asm/syscalls.h | 58 +++++
arch/c6x/include/asm/system.h | 194 ++++++++++++++++
arch/c6x/include/asm/termbits.h | 6 +
arch/c6x/include/asm/termios.h | 6 +
arch/c6x/include/asm/thread_info.h | 123 ++++++++++
arch/c6x/include/asm/timer.h | 31 +++
arch/c6x/include/asm/timex.h | 43 ++++
arch/c6x/include/asm/tlb.h | 8 +
arch/c6x/include/asm/tlbflush.h | 6 +
arch/c6x/include/asm/topology.h | 6 +
arch/c6x/include/asm/traps.h | 39 +++
arch/c6x/include/asm/types.h | 6 +
arch/c6x/include/asm/uaccess.h | 103 ++++++++
arch/c6x/include/asm/ucontext.h | 6 +
arch/c6x/include/asm/unaligned.h | 290 +++++++++++++++++++++++
arch/c6x/include/asm/unistd.h | 32 +++
arch/c6x/include/asm/user.h | 1 +
arch/c6x/include/asm/vga.h | 6 +
101 files changed, 4106 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/include/asm/Kbuild
create mode 100644 arch/c6x/include/asm/asm-offsets.h
create mode 100644 arch/c6x/include/asm/atomic.h
create mode 100644 arch/c6x/include/asm/auxvec.h
create mode 100644 arch/c6x/include/asm/bitops.h
create mode 100644 arch/c6x/include/asm/bitsperlong.h
create mode 100644 arch/c6x/include/asm/bug.h
create mode 100644 arch/c6x/include/asm/bugs.h
create mode 100644 arch/c6x/include/asm/byteorder.h
create mode 100644 arch/c6x/include/asm/cache.h
create mode 100644 arch/c6x/include/asm/cacheflush.h
create mode 100644 arch/c6x/include/asm/checksum.h
create mode 100644 arch/c6x/include/asm/clkdev.h
create mode 100644 arch/c6x/include/asm/clock.h
create mode 100644 arch/c6x/include/asm/cputime.h
create mode 100644 arch/c6x/include/asm/current.h
create mode 100644 arch/c6x/include/asm/delay.h
create mode 100644 arch/c6x/include/asm/device.h
create mode 100644 arch/c6x/include/asm/div64.h
create mode 100644 arch/c6x/include/asm/dma-mapping.h
create mode 100644 arch/c6x/include/asm/dma.h
create mode 100644 arch/c6x/include/asm/elf.h
create mode 100644 arch/c6x/include/asm/emergency-restart.h
create mode 100644 arch/c6x/include/asm/errno.h
create mode 100644 arch/c6x/include/asm/fb.h
create mode 100644 arch/c6x/include/asm/fcntl.h
create mode 100644 arch/c6x/include/asm/ftrace.h
create mode 100644 arch/c6x/include/asm/futex.h
create mode 100644 arch/c6x/include/asm/gemac.h
create mode 100644 arch/c6x/include/asm/gmdio.h
create mode 100644 arch/c6x/include/asm/hardirq.h
create mode 100644 arch/c6x/include/asm/hardware.h
create mode 100644 arch/c6x/include/asm/hw_irq.h
create mode 100644 arch/c6x/include/asm/io.h
create mode 100644 arch/c6x/include/asm/ioctl.h
create mode 100644 arch/c6x/include/asm/ioctls.h
create mode 100644 arch/c6x/include/asm/ipcbuf.h
create mode 100644 arch/c6x/include/asm/irq.h
create mode 100644 arch/c6x/include/asm/irq_regs.h
create mode 100644 arch/c6x/include/asm/irqflags.h
create mode 100644 arch/c6x/include/asm/kdebug.h
create mode 100644 arch/c6x/include/asm/kmap_types.h
create mode 100644 arch/c6x/include/asm/leds.h
create mode 100644 arch/c6x/include/asm/linkage.h
create mode 100644 arch/c6x/include/asm/local.h
create mode 100644 arch/c6x/include/asm/mman.h
create mode 100644 arch/c6x/include/asm/mmu.h
create mode 100644 arch/c6x/include/asm/mmu_context.h
create mode 100644 arch/c6x/include/asm/module.h
create mode 100644 arch/c6x/include/asm/msgbuf.h
create mode 100644 arch/c6x/include/asm/mutex.h
create mode 100644 arch/c6x/include/asm/page.h
create mode 100644 arch/c6x/include/asm/param.h
create mode 100644 arch/c6x/include/asm/pci.h
create mode 100644 arch/c6x/include/asm/percpu.h
create mode 100644 arch/c6x/include/asm/pgalloc.h
create mode 100644 arch/c6x/include/asm/pgtable.h
create mode 100644 arch/c6x/include/asm/pll.h
create mode 100644 arch/c6x/include/asm/pm.h
create mode 100644 arch/c6x/include/asm/poll.h
create mode 100644 arch/c6x/include/asm/posix_types.h
create mode 100644 arch/c6x/include/asm/processor.h
create mode 100644 arch/c6x/include/asm/procinfo.h
create mode 100644 arch/c6x/include/asm/ptrace.h
create mode 100644 arch/c6x/include/asm/resource.h
create mode 100644 arch/c6x/include/asm/scatterlist.h
create mode 100644 arch/c6x/include/asm/sections.h
create mode 100644 arch/c6x/include/asm/segment.h
create mode 100644 arch/c6x/include/asm/sembuf.h
create mode 100644 arch/c6x/include/asm/serial.h
create mode 100644 arch/c6x/include/asm/setup.h
create mode 100644 arch/c6x/include/asm/sgmii.h
create mode 100644 arch/c6x/include/asm/shmbuf.h
create mode 100644 arch/c6x/include/asm/shmparam.h
create mode 100644 arch/c6x/include/asm/sigcontext.h
create mode 100644 arch/c6x/include/asm/siginfo.h
create mode 100644 arch/c6x/include/asm/signal.h
create mode 100644 arch/c6x/include/asm/socket.h
create mode 100644 arch/c6x/include/asm/sockios.h
create mode 100644 arch/c6x/include/asm/stat.h
create mode 100644 arch/c6x/include/asm/statfs.h
create mode 100644 arch/c6x/include/asm/string.h
create mode 100644 arch/c6x/include/asm/swab.h
create mode 100644 arch/c6x/include/asm/syscalls.h
create mode 100644 arch/c6x/include/asm/system.h
create mode 100644 arch/c6x/include/asm/termbits.h
create mode 100644 arch/c6x/include/asm/termios.h
create mode 100644 arch/c6x/include/asm/thread_info.h
create mode 100644 arch/c6x/include/asm/timer.h
create mode 100644 arch/c6x/include/asm/timex.h
create mode 100644 arch/c6x/include/asm/tlb.h
create mode 100644 arch/c6x/include/asm/tlbflush.h
create mode 100644 arch/c6x/include/asm/topology.h
create mode 100644 arch/c6x/include/asm/traps.h
create mode 100644 arch/c6x/include/asm/types.h
create mode 100644 arch/c6x/include/asm/uaccess.h
create mode 100644 arch/c6x/include/asm/ucontext.h
create mode 100644 arch/c6x/include/asm/unaligned.h
create mode 100644 arch/c6x/include/asm/unistd.h
create mode 100644 arch/c6x/include/asm/user.h
create mode 100644 arch/c6x/include/asm/vga.h

diff --git a/arch/c6x/include/asm/Kbuild b/arch/c6x/include/asm/Kbuild
new file mode 100644
index 0000000..b200fda
--- /dev/null
+++ b/arch/c6x/include/asm/Kbuild
@@ -0,0 +1,2 @@
+include include/asm-generic/Kbuild.asm
+
diff --git a/arch/c6x/include/asm/asm-offsets.h b/arch/c6x/include/asm/asm-offsets.h
new file mode 100644
index 0000000..d370ee3
--- /dev/null
+++ b/arch/c6x/include/asm/asm-offsets.h
@@ -0,0 +1 @@
+#include <generated/asm-offsets.h>
diff --git a/arch/c6x/include/asm/atomic.h b/arch/c6x/include/asm/atomic.h
new file mode 100644
index 0000000..d995e0e
--- /dev/null
+++ b/arch/c6x/include/asm/atomic.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_ATOMIC_H
+#define _ASM_C6X_ATOMIC_H
+
+#include <asm-generic/atomic.h>
+
+#endif /* _ASM_C6X_ATOMIC_H */
diff --git a/arch/c6x/include/asm/auxvec.h b/arch/c6x/include/asm/auxvec.h
new file mode 100644
index 0000000..8d881e6
--- /dev/null
+++ b/arch/c6x/include/asm/auxvec.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_AUXVEC_H
+#define _ASM_C6X_AUXVEC_H
+
+#include <asm-generic/auxvec.h>
+
+#endif /* _ASM_C6X_AUXVEC_H */
diff --git a/arch/c6x/include/asm/bitops.h b/arch/c6x/include/asm/bitops.h
new file mode 100644
index 0000000..c7391b4
--- /dev/null
+++ b/arch/c6x/include/asm/bitops.h
@@ -0,0 +1,181 @@
+/*
+ * linux/include/asm-c6x/bitops.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_BITOPS_H
+#define _ASM_C6X_BITOPS_H
+
+#ifdef __KERNEL__
+
+#include <linux/bitops.h>
+
+#include <asm/system.h>
+#include <asm/byteorder.h>
+
+/*
+ * clear_bit() doesn't provide any barrier for the compiler.
+ */
+#define smp_mb__before_clear_bit() barrier()
+#define smp_mb__after_clear_bit() barrier()
+
+static inline void set_bit(int nr, volatile void *addr)
+{
+ volatile unsigned long *a = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *a |= mask;
+ local_irq_restore(flags);
+}
+
+static inline void clear_bit(int nr, volatile void *addr)
+{
+ volatile unsigned long *a = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *a &= ~mask;
+ local_irq_restore(flags);
+}
+
+static inline void change_bit(int nr, volatile void *addr)
+{
+ volatile unsigned long *a = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long flags;
+
+ local_irq_save(flags);
+ *a ^= mask;
+ local_irq_restore(flags);
+}
+
+static inline int test_and_set_bit(int nr, volatile void *addr)
+{
+ volatile unsigned long *a = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long flags;
+ int retval;
+
+ local_irq_save(flags);
+ retval = (mask & *a) != 0;
+ *a |= mask;
+ local_irq_restore(flags);
+ return retval;
+}
+
+static inline int test_and_clear_bit(int nr, volatile void *addr)
+{
+ unsigned long *a = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long retval;
+ unsigned long flags;
+
+ local_irq_save(flags);
+ retval = (mask & *a) != 0;
+ *a &= ~mask;
+ local_irq_restore(flags);
+ return retval;
+}
+
+static inline int test_and_change_bit(int nr, volatile void *addr)
+{
+ unsigned long *a = ((unsigned long *)addr) + BIT_WORD(nr);
+ unsigned long mask = BIT_MASK(nr);
+ unsigned long flags;
+ int retval;
+
+ local_irq_save(flags);
+ retval = (mask & *a) != 0;
+ *a ^= mask;
+ local_irq_restore(flags);
+ return retval;
+}
+
+/*
+ * We are lucky, DSP is perfect for bitops: do it in 3 cycles
+ */
+
+/**
+ * __ffs - find first bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ * Note __ffs(0) = undef, __ffs(1) = 0, __ffs(0x80000000) = 31.
+ *
+ */
+static inline unsigned long __ffs(unsigned long x)
+{
+ asm (" bitr .M1 %0,%0\n"
+ " nop\n"
+ " lmbd .L1 1,%0,%0\n"
+ : "+a"(x));
+
+ return x;
+}
+
+/*
+ * ffz - find first zero in word.
+ * @word: The word to search
+ *
+ * Undefined if no zero exists, so code should check against ~0UL first.
+ */
+#define ffz(x) __ffs(~(x))
+
+/**
+ * fls - find last (most-significant) bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as ffs.
+ * Note fls(0) = 0, fls(1) = 1, fls(0x80000000) = 32.
+ */
+static inline int fls(int x)
+{
+ if (!x)
+ return 0;
+
+ asm (" lmbd .L1 1,%0,%0\n" : "+a"(x));
+
+ return 32 - x;
+}
+
+/**
+ * ffs - find first bit set
+ * @x: the word to search
+ *
+ * This is defined the same way as
+ * the libc and compiler builtin ffs routines, therefore
+ * differs in spirit from the above ffz (man ffs).
+ * Note ffs(0) = 0, ffs(1) = 1, ffs(0x80000000) = 32.
+ */
+static inline int ffs(int x)
+{
+ if (!x)
+ return 0;
+
+ return __ffs(x) + 1;
+}
+
+#include <asm-generic/bitops/__fls.h>
+#include <asm-generic/bitops/fls64.h>
+#include <asm-generic/bitops/find.h>
+
+#include <asm-generic/bitops/sched.h>
+#include <asm-generic/bitops/hweight.h>
+#include <asm-generic/bitops/lock.h>
+
+#include <asm-generic/bitops/non-atomic.h>
+#include <asm-generic/bitops/le.h>
+#include <asm-generic/bitops/ext2-atomic.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_C6X_BITOPS_H */
diff --git a/arch/c6x/include/asm/bitsperlong.h b/arch/c6x/include/asm/bitsperlong.h
new file mode 100644
index 0000000..2cd2b80
--- /dev/null
+++ b/arch/c6x/include/asm/bitsperlong.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_BITSPERLONG_H
+#define _ASM_C6X_BITSPERLONG_H
+
+#include <asm-generic/bitsperlong.h>
+
+#endif /* _ASM_C6X_BITSPERLONG_H */
diff --git a/arch/c6x/include/asm/bug.h b/arch/c6x/include/asm/bug.h
new file mode 100644
index 0000000..6dbbb6e
--- /dev/null
+++ b/arch/c6x/include/asm/bug.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_BUG_H
+#define _ASM_C6X_BUG_H
+
+#include <asm-generic/bug.h>
+
+#endif /* _ASM_C6X_BUG_H */
diff --git a/arch/c6x/include/asm/bugs.h b/arch/c6x/include/asm/bugs.h
new file mode 100644
index 0000000..c810e54
--- /dev/null
+++ b/arch/c6x/include/asm/bugs.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_BUGS_H
+#define _ASM_C6X_BUGS_H
+
+#include <asm-generic/bugs.h>
+
+#endif /* _ASM_C6X_BUGS_H */
diff --git a/arch/c6x/include/asm/byteorder.h b/arch/c6x/include/asm/byteorder.h
new file mode 100644
index 0000000..166038d
--- /dev/null
+++ b/arch/c6x/include/asm/byteorder.h
@@ -0,0 +1,12 @@
+#ifndef _ASM_C6X_BYTEORDER_H
+#define _ASM_C6X_BYTEORDER_H
+
+#include <asm/types.h>
+
+#ifdef _BIG_ENDIAN
+#include <linux/byteorder/big_endian.h>
+#else /* _BIG_ENDIAN */
+#include <linux/byteorder/little_endian.h>
+#endif /* _BIG_ENDIAN */
+
+#endif /* _ASM_BYTEORDER_H */
diff --git a/arch/c6x/include/asm/cache.h b/arch/c6x/include/asm/cache.h
new file mode 100644
index 0000000..00f66a6
--- /dev/null
+++ b/arch/c6x/include/asm/cache.h
@@ -0,0 +1,373 @@
+/*
+ * linux/include/asm-c6x/cache.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_CACHE_H
+#define _ASM_C6X_CACHE_H
+
+#include <linux/irqflags.h>
+#include <asm/hardware.h>
+#include <mach/cache.h>
+
+/*
+ * Current C6x architecture does not support hw cache coherency
+ */
+#define arch_is_coherent() 0
+
+/*
+ * For practical reasons the L1_CACHE_BYTES defines should not be smaller than
+ * the L2 line size
+ */
+#define L1_CACHE_BYTES L2_CACHE_BYTES
+
+#define L2_CACHE_ALIGN_LOW(x) \
+ (((x) & ~(L2_CACHE_BYTES - 1)))
+#define L2_CACHE_ALIGN_UP(x) \
+ (((x) + (L2_CACHE_BYTES - 1)) & ~(L2_CACHE_BYTES - 1))
+#define L2_CACHE_ALIGN_CNT(x) \
+ (((x) + (sizeof(int) - 1)) & ~(sizeof(int) - 1))
+
+#define ARCH_DMA_MINALIGN L1_CACHE_BYTES
+#define ARCH_SLAB_MINALIGN L1_CACHE_BYTES
+
+/*
+ * Align a physical address to MAR regions
+ */
+#define CACHE_REGION_START(v) (((u32) (v)) & ~(IMCR_MAR_SIZE - 1))
+#define CACHE_REGION_END(v) (((u32) (v) + (IMCR_MAR_SIZE - 1)) & ~(IMCR_MAR_SIZE - 1))
+
+/*
+ * CCFG register values and bits
+ */
+#define L2MODE_0K_CACHE 0x0
+#define L2MODE_32K_CACHE 0x1
+#define L2MODE_64K_CACHE 0x2
+#define L2MODE_128K_CACHE 0x3
+#define L2MODE_256K_CACHE 0x7
+
+#define L2PRIO_URGENT 0x0
+#define L2PRIO_HIGH 0x1
+#define L2PRIO_MEDIUM 0x2
+#define L2PRIO_LOW 0x3
+
+#define CCFG_ID 0x100 /* Invalidate L1P bit */
+#define CCFG_IP 0x200 /* Invalidate L1D bit */
+
+/*
+ * L1 & L2 caches generic functions
+ */
+#define imcr_get(reg) (*((volatile unsigned int *) (reg)))
+#define imcr_set(reg, value) \
+ do { \
+ *((volatile unsigned int *) (reg)) = (value); \
+ (value) = *((volatile unsigned int *) (reg)); \
+ } while (0)
+
+/*
+ * Generic function to perform a block cache operation as
+ * invalidate or writeback/invalidate
+ */
+static inline void cache_block_operation(unsigned int *start,
+ unsigned int *end,
+ unsigned int bar_reg,
+ unsigned int wc_reg)
+{
+ unsigned long flags;
+ unsigned int wcnt =
+ (L2_CACHE_ALIGN_CNT((unsigned int) end)
+ - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
+ unsigned int wc = 0;
+
+ for (; wcnt; wcnt -= wc, start += wc) {
+loop:
+ local_irq_save(flags);
+
+ /*
+ * If another cache operation is occuring
+ */
+ if (unlikely(*((volatile unsigned int *) wc_reg))) {
+ local_irq_restore(flags);
+
+ /* Wait for previous operation completion */
+ while (*((volatile unsigned int *) wc_reg))
+ ;
+
+ /* Try again */
+ goto loop;
+ }
+
+ *((volatile unsigned int *) bar_reg) =
+ L2_CACHE_ALIGN_LOW((unsigned int) start);
+
+ if (wcnt > 0xffff)
+ wc = 0xffff;
+ else
+ wc = wcnt;
+
+ /* Set word count value in the WC register */
+ *((volatile unsigned int *) wc_reg) = wc & 0xffff;
+
+ local_irq_restore(flags);
+
+ /* Wait for completion */
+ while (*((volatile unsigned int *) wc_reg))
+ ;
+ }
+}
+
+static inline void cache_block_operation_nowait(unsigned int *start,
+ unsigned int *end,
+ unsigned int bar_reg,
+ unsigned int wc_reg)
+{
+ unsigned long flags;
+ unsigned int wcnt =
+ (L2_CACHE_ALIGN_CNT((unsigned int) end)
+ - L2_CACHE_ALIGN_LOW((unsigned int) start)) >> 2;
+ unsigned int wc = 0;
+
+ for (; wcnt; wcnt -= wc, start += wc) {
+
+ local_irq_save(flags);
+
+ *((volatile unsigned int *) bar_reg) =
+ L2_CACHE_ALIGN_LOW((unsigned int) start);
+
+ if (wcnt > 0xffff)
+ wc = 0xffff;
+ else
+ wc = wcnt;
+
+ /* Set word count value in the WC register */
+ *((volatile unsigned int *) wc_reg) = wc & 0xffff;
+
+ local_irq_restore(flags);
+
+ /* Don't wait for completion on last cache operation */
+ if (wcnt > 0xffff)
+ while (*((volatile unsigned int *) wc_reg))
+ ;
+ }
+}
+
+static inline void cache_block_operation_wait(unsigned int wc_reg)
+{
+ /* Wait for completion */
+ while (*((volatile unsigned int *) wc_reg))
+ ;
+}
+
+/*
+ * L1 caches management
+ */
+
+/*
+ * Disable L1 caches
+ */
+static inline void L1_cache_off(void)
+{
+ unsigned int cfg = 0;
+ imcr_set(IMCR_L1PCFG, cfg);
+ imcr_set(IMCR_L1DCFG, cfg);
+}
+
+/*
+ * Enable L1 caches
+ */
+static inline void L1_cache_on(void)
+{
+ unsigned int cfg = 7;
+ imcr_set(IMCR_L1PCFG, cfg);
+ imcr_set(IMCR_L1DCFG, cfg);
+}
+
+/*
+ * L1P global-invalidate all
+ */
+static inline void L1P_cache_global_invalidate(void)
+{
+ unsigned int set = 1;
+ imcr_set(IMCR_L1PINV, set);
+ while (imcr_get(IMCR_L1PINV) & 1)
+ ;
+}
+
+/*
+ * L1D global-invalidate all
+ *
+ * Warning: this operation causes all updated data in L1D to
+ * be discarded rather than written back to the lower levels of
+ * memory
+ */
+static inline void L1D_cache_global_invalidate(void)
+{
+ unsigned int set = 1;
+ imcr_set(IMCR_L1DINV, set);
+ while (imcr_get(IMCR_L1DINV) & 1)
+ ;
+}
+
+static inline void L1D_cache_global_writeback(void)
+{
+ unsigned int set = 1;
+ imcr_set(IMCR_L1DWB, set);
+ while (imcr_get(IMCR_L1DWB) & 1)
+ ;
+}
+
+static inline void L1D_cache_global_writeback_invalidate(void)
+{
+ unsigned int set = 1;
+ imcr_set(IMCR_L1DWBINV, set);
+ while (imcr_get(IMCR_L1DWBINV) & 1)
+ ;
+}
+
+/*
+ * L1 block operations
+ */
+#define L1P_cache_block_invalidate(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L1PIBAR, IMCR_L1PIWC)
+
+#define L1D_cache_block_invalidate(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L1DIBAR, IMCR_L1DIWC)
+
+#define L1D_cache_block_writeback_invalidate(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L1DWIBAR, IMCR_L1DWIWC)
+
+#define L1D_cache_block_writeback(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L1DWBAR, IMCR_L1DWWC)
+
+#ifdef CONFIG_TMS320C6X_CACHES_ON
+/*
+ * L2 caches management
+ */
+
+/*
+ * Set L2 operation mode
+ */
+static inline void L2_cache_set_mode(unsigned int mode)
+{
+ unsigned int ccfg = imcr_get(IMCR_CCFG);
+
+ /* Clear and set the L2MODE bits in CCFG */
+ ccfg &= ~7;
+ ccfg |= (mode & 7);
+ imcr_set(IMCR_CCFG, ccfg);
+}
+
+/*
+ * L2 global-writeback and global-invalidate all
+ */
+static inline void L2_cache_global_writeback_invalidate(void)
+{
+ *((volatile unsigned int *) (IMCR_L2WBINV)) = 1;
+ while (*((volatile unsigned int *) (IMCR_L2WBINV)))
+ ;
+}
+
+/*
+ * L2 global-writeback all
+ */
+static inline void L2_cache_global_writeback(void)
+{
+ *((volatile unsigned int *) (IMCR_L2WB)) = 1;
+ while (*((volatile unsigned int *) (IMCR_L2WB)))
+ ;
+}
+
+/*
+ * L2 block operations
+ */
+#define L2_cache_block_invalidate(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L2IBAR, IMCR_L2IWC)
+
+#define L2_cache_block_writeback(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L2WBAR, IMCR_L2WWC)
+
+#define L2_cache_block_writeback_invalidate(start, end) \
+ cache_block_operation((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L2WIBAR, IMCR_L2WIWC)
+
+#define L2_cache_block_invalidate_nowait(start, end) \
+ cache_block_operation_nowait((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L2IBAR, IMCR_L2IWC)
+
+#define L2_cache_block_invalidate_wait() \
+ cache_block_operation_wait(IMCR_L2IWC)
+
+#define L2_cache_block_writeback_nowait(start, end) \
+ cache_block_operation_nowait((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L2WBAR, IMCR_L2WWC)
+
+#define L2_cache_block_writeback_wait() \
+ cache_block_operation_wait(IMCR_L2WWC)
+
+#define L2_cache_block_writeback_invalidate_nowait(start, end) \
+ cache_block_operation_nowait((unsigned int *) (start), \
+ (unsigned int *) (end), \
+ IMCR_L2WIBAR, IMCR_L2WIWC)
+
+#define L2_cache_block_writeback_invalidate_wait() \
+ cache_block_operation_wait(IMCR_L2WIWC)
+
+/*
+ * Cacheability controls
+ */
+static inline void enable_caching(unsigned long start, unsigned long end)
+{
+ unsigned int *mar = (unsigned int *) IMCR_MAR_BASE + (start >> 24);
+ unsigned int *mar_e = (unsigned int *) IMCR_MAR_BASE + (end >> 24);
+
+ for (; mar <= mar_e; mar++)
+ *mar |= 1;
+}
+
+static inline void disable_caching(unsigned long start, unsigned long end)
+{
+ unsigned int *mar = (unsigned int *) IMCR_MAR_BASE + (start >> 24);
+ unsigned int *mar_e = (unsigned int *) IMCR_MAR_BASE + (end >> 24);
+
+ for (; mar <= mar_e; mar++)
+ *mar &= ~1;
+}
+
+#else /* CONFIG_TMS320C6X_CACHES_ON */
+#define L2_cache_set_mode(mode)
+#define L2_cache_global_writeback_invalidate()
+#define L2_cache_global_writeback()
+#define L2_cache_block_invalidate(start, end)
+#define L2_cache_block_writeback(start, end)
+#define L2_cache_block_writeback_invalidate(start, end)
+#define L2_cache_block_invalidate_nowait(start, end)
+#define L2_cache_block_invalidate_wait()
+#define L2_cache_block_writeback_nowait(start, end)
+#define L2_cache_block_writeback_wait()
+#define L2_cache_block_writeback_invalidate_nowait(start, end)
+#define L2_cache_block_writeback_invalidate_wait()
+
+#endif /* CONFIG_TMS320C6X_CACHES_ON */
+#endif /* _ASM_C6X_CACHE_H */
diff --git a/arch/c6x/include/asm/cacheflush.h b/arch/c6x/include/asm/cacheflush.h
new file mode 100644
index 0000000..f56fa4c
--- /dev/null
+++ b/arch/c6x/include/asm/cacheflush.h
@@ -0,0 +1,67 @@
+/*
+ * linux/include/asm-c6x/pgalloc.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_CACHEFLUSH_H
+#define _ASM_C6X_CACHEFLUSH_H
+
+#include <linux/spinlock.h>
+
+#include <asm/setup.h>
+#include <asm/cache.h>
+#include <asm/mman.h>
+#include <asm/page.h>
+#include <asm/string.h>
+
+/*
+ * virtually-indexed cache management (our cache is physically indexed)
+ */
+#define flush_cache_all() do {} while (0)
+#define flush_cache_mm(mm) do {} while (0)
+#define flush_cache_dup_mm(mm) do {} while (0)
+#define flush_cache_range(mm, start, end) do {} while (0)
+#define flush_cache_page(vma, vmaddr, pfn) do {} while (0)
+#define flush_cache_vmap(start, end) do {} while (0)
+#define flush_cache_vunmap(start, end) do {} while (0)
+#define ARCH_IMPLEMENTS_FLUSH_DCACHE_PAGE 0
+#define flush_dcache_page(page) do {} while (0)
+#define flush_dcache_mmap_lock(mapping) do {} while (0)
+#define flush_dcache_mmap_unlock(mapping) do {} while (0)
+
+/*
+ * physically-indexed cache management
+ */
+#define flush_icache_range(s, e) \
+ do { \
+ L1D_cache_block_writeback((s), (e)); \
+ L1P_cache_block_invalidate((s), (e)); \
+ } while (0)
+
+#define flush_icache_page(vma, page) \
+do { \
+ if ((vma)->vm_flags & PROT_EXEC) \
+ L1D_cache_block_writeback_invalidate(page_address(page), \
+ (unsigned long) page_address(page) + PAGE_SIZE)); \
+ L1P_cache_block_invalidate(page_address(page), \
+ (unsigned long) page_address(page) + PAGE_SIZE)); \
+} while (0)
+
+
+#define copy_to_user_page(vma, page, vaddr, dst, src, len) \
+do { \
+ memcpy(dst, src, len); \
+ flush_icache_range((unsigned) (dst), (unsigned) (dst) + (len)); \
+} while (0)
+
+#define copy_from_user_page(vma, page, vaddr, dst, src, len) \
+ memcpy(dst, src, len)
+
+#endif /* _ASM_C6X_CACHEFLUSH_H */
diff --git a/arch/c6x/include/asm/checksum.h b/arch/c6x/include/asm/checksum.h
new file mode 100644
index 0000000..9813a80
--- /dev/null
+++ b/arch/c6x/include/asm/checksum.h
@@ -0,0 +1,116 @@
+/*
+ * linux/include/asm-c6x/checksum.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_CHECKSUM_H
+#define _ASM_C6X_CHECKSUM_H
+
+#include <asm/byteorder.h>
+
+/*
+ * 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
+ */
+extern __wsum csum_partial(const void *buff, int len, __wsum sum);
+
+/*
+ * The same as csum_partial, but copies from src while it checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+extern __wsum csum_partial_copy(const void *src, void *dst, int len, __wsum 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.
+ */
+#define csum_partial_copy_nocheck csum_partial_copy
+
+/*
+ * The same as csum_partial_copy, but copies from user space.
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+#define csum_partial_copy_from_user(src, dst, len, sum, err_ptr) \
+ csum_partial_copy(src, dst, len, sum)
+
+/*
+ * This is a version of ip_compute_csum() optimized for IP headers,
+ * which always checksum on 4 octet boundaries.
+ *
+ */
+extern __sum16 ip_fast_csum(const void *iph, unsigned int ihl);
+
+/*
+ * Fold a partial checksum
+ */
+static inline __sum16 csum_fold(__wsum csum)
+{
+ u32 sum = (u32)csum;
+ sum = (sum & 0xffff) + (sum >> 16);
+ sum = (sum & 0xffff) + (sum >> 16);
+ return (__sum16)~sum;
+}
+
+/*
+ * Computes the checksum of the TCP/UDP pseudo-header
+ */
+static inline __wsum
+csum_tcpudp_nofold(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum sum)
+{
+ unsigned long long s = (__force u32)sum;
+
+ s += (__force u32)saddr;
+ s += (__force u32)daddr;
+#ifdef _BIG_ENDIAN
+ s += proto + len;
+#else
+ s += (proto + len) << 8;
+#endif
+ s += (s >> 32);
+
+ return (__force __wsum)s;
+}
+
+/*
+ * Computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+static inline __sum16
+csum_tcpudp_magic(__be32 saddr, __be32 daddr, unsigned short len,
+ unsigned short proto, __wsum 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 __sum16
+ip_compute_csum(const void *buff, int len)
+{
+ extern unsigned int do_csum(const unsigned char *, size_t);
+ return (__force __sum16)~do_csum(buff, len);
+}
+
+#endif /* _ASM_C6X_CHECKSUM_H */
diff --git a/arch/c6x/include/asm/clkdev.h b/arch/c6x/include/asm/clkdev.h
new file mode 100644
index 0000000..aff359c
--- /dev/null
+++ b/arch/c6x/include/asm/clkdev.h
@@ -0,0 +1,45 @@
+/*
+ * arch/c6x/include/asm/clkdev.h
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * Original code from: arch/arm/include/asm/clkdev.h
+ *
+ * Copyright (C) 2008 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#ifndef _ASM_CLKDEV_H
+#define _ASM_CLKDEV_H
+
+struct clk;
+struct device;
+
+struct clk_lookup {
+ struct list_head node;
+ const char *dev_id;
+ const char *con_id;
+ struct clk *clk;
+};
+
+struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+ const char *dev_fmt, ...);
+
+void clkdev_add(struct clk_lookup *cl);
+void clkdev_drop(struct clk_lookup *cl);
+
+void clkdev_add_table(struct clk_lookup *, size_t);
+int clk_add_alias(const char *, const char *, char *, struct device *);
+
+int __clk_get(struct clk *clk);
+void __clk_put(struct clk *clk);
+
+int clk_register(struct clk *clk);
+void clk_unregister(struct clk *clk);
+
+#endif /* _ASM_CLKDEV_H */
diff --git a/arch/c6x/include/asm/clock.h b/arch/c6x/include/asm/clock.h
new file mode 100644
index 0000000..d8f1a77
--- /dev/null
+++ b/arch/c6x/include/asm/clock.h
@@ -0,0 +1,73 @@
+/*
+ * TI C64X clock definitions
+ *
+ * Copyright (C) 2010 Texas Instruments.
+ * Contributed by: Mark Salter <[email protected]>
+ *
+ * Copied heavily from arm/mach-davinci/clock.h, so:
+ *
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * 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_C6X_CLOCK_H
+#define _ASM_C6X_CLOCK_H
+
+#include <mach/pll.h>
+
+#ifndef __ASSEMBLER__
+
+#include <linux/list.h>
+#include <asm/clkdev.h>
+
+struct pll_data {
+ u32 phys_base;
+ void __iomem *base;
+ u32 num;
+ u32 flags;
+ u32 input_rate;
+};
+#define PLL_HAS_PREDIV 0x01
+
+struct clk {
+ struct list_head node;
+ struct module *owner;
+ const char *name;
+ unsigned long rate;
+ int usecount;
+ u32 flags;
+ struct clk *parent;
+ struct list_head children; /* list of children */
+ struct list_head childnode; /* parent's child list node */
+ struct pll_data *pll_data;
+ u32 div;
+ unsigned long (*recalc) (struct clk *);
+ int (*set_rate) (struct clk *clk, unsigned long rate);
+ int (*round_rate) (struct clk *clk, unsigned long rate);
+};
+
+/* Clock flags: SoC-specific flags start at BIT(16) */
+#define ALWAYS_ENABLED BIT(1)
+#define CLK_PLL BIT(2) /* PLL-derived clock */
+#define PRE_PLL BIT(3) /* source is before PLL mult/div */
+#define FIXED_DIV_PLL BIT(4) /* fixed divisor from PLL */
+#define FIXED_RATE_PLL BIT(5) /* fixed ouput rate PLL */
+
+#define CLK(dev, con, ck) \
+ { \
+ .dev_id = dev, \
+ .con_id = con, \
+ .clk = ck, \
+ } \
+
+int c6x_clk_init(struct clk_lookup *clocks);
+int c6x_set_pllrate(struct pll_data *pll, unsigned int prediv,
+ unsigned int mult);
+
+#endif
+
+#endif /* _ASM_C6X_CLOCK_H */
diff --git a/arch/c6x/include/asm/cputime.h b/arch/c6x/include/asm/cputime.h
new file mode 100644
index 0000000..e352391
--- /dev/null
+++ b/arch/c6x/include/asm/cputime.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_CPUTIME_H
+#define _ASM_C6X_CPUTIME_H
+
+#include <asm-generic/cputime.h>
+
+#endif /* _ASM_C6X_CPUTIME_H */
diff --git a/arch/c6x/include/asm/current.h b/arch/c6x/include/asm/current.h
new file mode 100644
index 0000000..7841d42
--- /dev/null
+++ b/arch/c6x/include/asm/current.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_CURRENT_H
+#define _ASM_C6X_CURRENT_H
+
+#include <asm-generic/current.h>
+
+#endif /* _ASM_C6X_CURRENT_H */
diff --git a/arch/c6x/include/asm/delay.h b/arch/c6x/include/asm/delay.h
new file mode 100644
index 0000000..d18f3b8
--- /dev/null
+++ b/arch/c6x/include/asm/delay.h
@@ -0,0 +1,69 @@
+/*
+ * linux/include/asm-c6x/delay.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_DELAY_H
+#define _ASM_C6X_DELAY_H
+
+#include <linux/kernel.h>
+
+extern unsigned int ticks_per_ns_scaled;
+
+static inline void __delay(unsigned long loops)
+{
+ uint32_t tmp;
+
+ /* 6 cycles per loop */
+ asm volatile (" mv .s1 %0,%1\n"
+ "0: [%1] b .s1 0b\n"
+ " add .l1 -6,%0,%0\n"
+ " cmplt .l1 1,%0,%1\n"
+ " nop 3\n"
+ : "+a"(loops), "=A"(tmp));
+}
+
+static inline void _c6x_tickdelay(unsigned int x)
+{
+ uint32_t cnt, endcnt;
+
+ asm volatile (" mvc .s2 TSCL,%0\n"
+ " add .s2x %0,%1,%2\n"
+ " || mvk .l2 1,B0\n"
+ "0: [B0] b .s2 0b\n"
+ " mvc .s2 TSCL,%0\n"
+ " sub .s2 %0,%2,%0\n"
+ " cmpgt .l2 0,%0,B0\n"
+ " nop 2\n"
+ : "=b"(cnt), "+a"(x), "=b"(endcnt) : : "B0");
+}
+
+/* use scaled math to avoid slow division */
+#define C6X_NDELAY_SCALE 10
+
+static inline void _ndelay(unsigned int n)
+{
+ _c6x_tickdelay((ticks_per_ns_scaled * n) >> C6X_NDELAY_SCALE);
+}
+
+static inline void _udelay(unsigned int n)
+{
+ while (n >= 10) {
+ _ndelay(10000);
+ n -= 10;
+ }
+ while (n-- > 0)
+ _ndelay(1000);
+}
+
+#define udelay(x) _udelay((unsigned int)(x))
+#define ndelay(x) _ndelay((unsigned int)(x))
+
+#endif /* _ASM_C6X_DELAY_H */
diff --git a/arch/c6x/include/asm/device.h b/arch/c6x/include/asm/device.h
new file mode 100644
index 0000000..0313e82
--- /dev/null
+++ b/arch/c6x/include/asm/device.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_DEVICE_H
+#define _ASM_C6X_DEVICE_H
+
+#include <asm-generic/device.h>
+
+#endif /* _ASM_C6X_DEVICE_H */
diff --git a/arch/c6x/include/asm/div64.h b/arch/c6x/include/asm/div64.h
new file mode 100644
index 0000000..46943e6
--- /dev/null
+++ b/arch/c6x/include/asm/div64.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_DIV64_H
+#define _ASM_C6X_DIV64_H
+
+#include <asm-generic/div64.h>
+
+#endif /* _ASM_C6X_DIV64_H */
diff --git a/arch/c6x/include/asm/dma-mapping.h b/arch/c6x/include/asm/dma-mapping.h
new file mode 100644
index 0000000..52aa79b
--- /dev/null
+++ b/arch/c6x/include/asm/dma-mapping.h
@@ -0,0 +1,302 @@
+/*
+ * linux/arch/c6x/include/asm/dma-mapping.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot <[email protected]>
+ *
+ * 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_C6X_DMA_MAPPING_H
+#define _ASM_C6X_DMA_MAPPING_H
+
+#ifdef __KERNEL__
+
+#include <linux/mm.h>
+#include <linux/mm_types.h>
+#include <linux/scatterlist.h>
+
+#include <asm/io.h>
+#include <asm/types.h>
+#include <asm-generic/dma-coherent.h>
+
+#define dma_supported(d, m) (1)
+
+#define __pfn_to_bus(pfn) ((pfn) << PAGE_SHIFT)
+#define __bus_to_pfn(paddr) ((paddr) >> PAGE_SHIFT)
+#define __bus_to_phys(x) (x)
+#define __phys_to_bus(x) (x)
+#define __bus_to_virt(b) phys_to_virt(__bus_to_phys(b))
+#define __virt_to_bus(v) __phys_to_bus(virt_to_phys(v))
+
+/*
+ * page_to_dma/dma_to_virt/virt_to_dma are architecture private functions
+ * used internally by the DMA-mapping API to provide DMA addresses. They
+ * must not be used by drivers.
+ */
+static inline dma_addr_t page_to_dma(struct device *dev, struct page *page)
+{
+ return (dma_addr_t)__pfn_to_bus(page_to_pfn(page));
+}
+
+static inline struct page *dma_to_page(struct device *dev, dma_addr_t addr)
+{
+ return pfn_to_page(__bus_to_pfn(addr));
+}
+
+static inline void *dma_to_virt(struct device *dev, dma_addr_t addr)
+{
+ return (void *)__bus_to_virt(addr);
+}
+
+static inline dma_addr_t virt_to_dma(struct device *dev, void *addr)
+{
+ return (dma_addr_t)__virt_to_bus(addr);
+}
+
+static inline int dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
+ enum dma_data_direction direction)
+{
+ struct scatterlist *sg;
+ int i;
+
+ BUG_ON(direction == DMA_NONE);
+
+ for_each_sg(sglist, sg, nents, i) {
+ BUG_ON(!sg_page(sg));
+
+ sg->dma_address = sg_phys(sg);
+ }
+
+ return nents;
+}
+
+static inline void dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+ enum dma_data_direction direction)
+{
+ BUG_ON(direction == DMA_NONE);
+}
+
+extern int __dma_is_coherent(struct device *dev, dma_addr_t handle);
+
+static inline int dma_is_consistent(struct device *dev, dma_addr_t handle)
+{
+ if (arch_is_coherent() || __dma_is_coherent(dev, handle))
+ return 1;
+ else
+ 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;
+}
+
+/**
+ * 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 *, size_t, dma_addr_t *, gfp_t);
+
+/**
+ * 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 *, size_t, void *, dma_addr_t);
+
+#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent((d), (s), (h), (f))
+#define dma_free_noncoherent(d, s, v, h) dma_free_coherent((d), (s), (v), (h))
+
+extern void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
+ enum dma_data_direction dir);
+
+extern void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
+ enum dma_data_direction dir);
+
+extern void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir);
+
+extern void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir);
+
+/**
+ * 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().
+ */
+static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
+ size_t size, enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ __dma_single_cpu_to_dev(cpu_addr, size, dir);
+
+ return virt_to_dma(dev, cpu_addr);
+}
+
+/**
+ * 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().
+ */
+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)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ __dma_page_cpu_to_dev(page, offset, size, dir);
+
+ return page_to_dma(dev, page) + offset;
+}
+
+/**
+ * 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 (same as passed to dma_map_single)
+ * @dir: DMA transfer direction (same as passed to dma_map_single)
+ *
+ * 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_single(struct device *dev, dma_addr_t handle,
+ size_t size, enum dma_data_direction dir)
+{
+ __dma_single_dev_to_cpu(dma_to_virt(dev, handle), size, dir);
+}
+
+/**
+ * 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 (same as passed to dma_map_page)
+ * @dir: DMA transfer direction (same as passed to dma_map_page)
+ *
+ * Unmap a page streaming mode DMA translation. The handle and size
+ * must match what was provided in the previous dma_map_page() 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_page_dev_to_cpu(dma_to_page(dev, handle), handle & ~PAGE_MASK,
+ size, dir);
+}
+
+/**
+ * dma_sync_single_range_for_cpu
+ * @dev: valid struct device pointer, or NULL for ISA and EISA-like devices
+ * @handle: DMA address of buffer
+ * @offset: offset of region to start sync
+ * @size: size of region to sync
+ * @dir: DMA transfer direction (same as passed to dma_map_single)
+ *
+ * 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.
+ */
+static inline void dma_sync_single_range_for_cpu(struct device *dev,
+ dma_addr_t handle, unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ __dma_single_dev_to_cpu(dma_to_virt(dev, handle) + offset, size, dir);
+}
+
+static inline void dma_sync_single_range_for_device(struct device *dev,
+ dma_addr_t handle, unsigned long offset, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+
+ __dma_single_cpu_to_dev(dma_to_virt(dev, handle) + offset, size, dir);
+}
+
+static inline void dma_sync_single_for_cpu(struct device *dev,
+ dma_addr_t handle, size_t size, enum dma_data_direction dir)
+{
+ dma_sync_single_range_for_cpu(dev, handle, 0, 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)
+{
+ dma_sync_single_range_for_device(dev, handle, 0, size, dir);
+}
+
+static inline void
+dma_sync_sg_for_cpu(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+}
+
+static inline void
+dma_sync_sg_for_device(struct device *dev, struct scatterlist *sg, int nents,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!valid_dma_direction(dir));
+}
+
+extern int coherent_mem_init(void);
+extern unsigned long dma_memory_start;
+extern unsigned long dma_memory_size;
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_C6X_DMA_MAPPING_H */
diff --git a/arch/c6x/include/asm/dma.h b/arch/c6x/include/asm/dma.h
new file mode 100644
index 0000000..0431395
--- /dev/null
+++ b/arch/c6x/include/asm/dma.h
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-c6x/dma.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_DMA_H
+#define _ASM_C6X_DMA_H
+
+#define MAX_DMA_ADDRESS 0xFFFFFFFF
+#define MAX_DMA_CHANNELS 64
+
+/* Reserve a DMA channel */
+extern int request_dma(unsigned int dmanr, const char *device_id);
+
+/* Release it again */
+extern void free_dma(unsigned int dmanr);
+
+#endif /* _ASM_C6X_DMA_H */
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h
new file mode 100644
index 0000000..272c3ae
--- /dev/null
+++ b/arch/c6x/include/asm/elf.h
@@ -0,0 +1,115 @@
+/*
+ * linux/include/asm-c6x/elf.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_ELF_H
+#define _ASM_C6X_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+#include <asm/ptrace.h>
+
+typedef unsigned long elf_greg_t;
+typedef unsigned long elf_fpreg_t;
+
+#define ELF_NGREG 58
+#define ELF_NFPREG 1
+
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000)
+
+#define elf_check_const_displacement(x) (1)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#ifdef __LITTLE_ENDIAN__
+#define ELF_DATA ELFDATA2LSB
+#else
+#define ELF_DATA ELFDATA2MSB
+#endif
+
+#define ELF_CLASS ELFCLASS32
+#define ELF_ARCH EM_TI_C6000
+
+/* Nothing for now. Need to setup DP... */
+#define ELF_PLAT_INIT(_r)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE 4096
+
+#define ELF_CORE_COPY_REGS(_dest, _regs) \
+ memcpy((char *) &_dest, (char *) _regs, \
+ sizeof(struct pt_regs));
+
+/* This yields a mask that user programs can use to figure out what
+ instruction set this cpu supports. */
+
+#define ELF_HWCAP (0)
+
+/* 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. */
+
+#define ELF_PLATFORM (NULL)
+
+#define SET_PERSONALITY(ex) set_personality(PER_LINUX)
+
+/* C6X specific section types */
+#define SHT_C6000_UNWIND 0x70000001
+#define SHT_C6000_PREEMPTMAP 0x70000002
+#define SHT_C6000_ATTRIBUTES 0x70000003
+
+/* C6X specific DT_ tags */
+#define DT_C6000_DSBT_BASE 0x70000000
+#define DT_C6000_DSBT_SIZE 0x70000001
+#define DT_C6000_PREEMPTMAP 0x70000002
+#define DT_C6000_DSBT_INDEX 0x70000003
+
+/* C6X specific relocs */
+#define R_C6000_NONE 0
+#define R_C6000_ABS32 1
+#define R_C6000_ABS16 2
+#define R_C6000_ABS8 3
+#define R_C6000_PCR_S21 4
+#define R_C6000_PCR_S12 5
+#define R_C6000_PCR_S10 6
+#define R_C6000_PCR_S7 7
+#define R_C6000_ABS_S16 8
+#define R_C6000_ABS_L16 9
+#define R_C6000_ABS_H16 10
+#define R_C6000_SBR_U15_B 11
+#define R_C6000_SBR_U15_H 12
+#define R_C6000_SBR_U15_W 13
+#define R_C6000_SBR_S16 14
+#define R_C6000_SBR_L16_B 15
+#define R_C6000_SBR_L16_H 16
+#define R_C6000_SBR_L16_W 17
+#define R_C6000_SBR_H16_B 18
+#define R_C6000_SBR_H16_H 19
+#define R_C6000_SBR_H16_W 20
+#define R_C6000_SBR_GOT_U15_W 21
+#define R_C6000_SBR_GOT_L16_W 22
+#define R_C6000_SBR_GOT_H16_W 23
+#define R_C6000_DSBT_INDEX 24
+#define R_C6000_PREL31 25
+#define R_C6000_COPY 26
+#define R_C6000_ALIGN 253
+#define R_C6000_FPHEAD 254
+#define R_C6000_NOCMP 255
+
+#endif /*_ASM_C6X_ELF_H */
diff --git a/arch/c6x/include/asm/emergency-restart.h b/arch/c6x/include/asm/emergency-restart.h
new file mode 100644
index 0000000..6cc0cf1
--- /dev/null
+++ b/arch/c6x/include/asm/emergency-restart.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_EMERGENCY_RESTART_H
+#define _ASM_C6X_EMERGENCY_RESTART_H
+
+#include <asm-generic/emergency-restart.h>
+
+#endif /* _ASM_C6X_EMERGENCY_RESTART_H */
diff --git a/arch/c6x/include/asm/errno.h b/arch/c6x/include/asm/errno.h
new file mode 100644
index 0000000..7f74f4a
--- /dev/null
+++ b/arch/c6x/include/asm/errno.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_ERRNO_H
+#define _ASM_C6X_ERRNO_H
+
+#include <asm-generic/errno.h>
+
+#endif /* _ASM_C6X_ERRNO_H */
diff --git a/arch/c6x/include/asm/fb.h b/arch/c6x/include/asm/fb.h
new file mode 100644
index 0000000..392e52a
--- /dev/null
+++ b/arch/c6x/include/asm/fb.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_FB_H
+#define _ASM_C6X_FB_H
+
+#include <asm-generic/fb.h>
+
+#endif /* _ASM_C6X_FB_H */
diff --git a/arch/c6x/include/asm/fcntl.h b/arch/c6x/include/asm/fcntl.h
new file mode 100644
index 0000000..7a8f9eb
--- /dev/null
+++ b/arch/c6x/include/asm/fcntl.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_FCNTL_H
+#define _ASM_C6X_FCNTL_H
+
+#include <asm-generic/fcntl.h>
+
+#endif /* _ASM_C6X_FCNTL_H */
diff --git a/arch/c6x/include/asm/ftrace.h b/arch/c6x/include/asm/ftrace.h
new file mode 100644
index 0000000..3701958
--- /dev/null
+++ b/arch/c6x/include/asm/ftrace.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_FTRACE_H
+#define _ASM_C6X_FTRACE_H
+
+/* empty */
+
+#endif /* _ASM_C6X_FTRACE_H */
diff --git a/arch/c6x/include/asm/futex.h b/arch/c6x/include/asm/futex.h
new file mode 100644
index 0000000..d492f20
--- /dev/null
+++ b/arch/c6x/include/asm/futex.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_FUTEX_H
+#define _ASM_C6X_FUTEX_H
+
+#include <asm-generic/futex.h>
+
+#endif /* _ASM_C6X_FUTEX_H */
diff --git a/arch/c6x/include/asm/gemac.h b/arch/c6x/include/asm/gemac.h
new file mode 100644
index 0000000..c73c65a
--- /dev/null
+++ b/arch/c6x/include/asm/gemac.h
@@ -0,0 +1,146 @@
+/*
+ * linux/include/asm-c6x/gemac.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Nicolas Videau <[email protected]>
+ * Aurelien Jacquiot <[email protected]>
+ *
+ *
+ * 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_C6X_GEMAC_H
+#define _ASM_C6X_GEMAC_H
+
+#ifdef __KERNEL__
+
+/*
+ * Tx and Rx buffers parameters (total should be lower than 512)
+ */
+#define QUEUE_NUM 8 /* Number of queues in the EMAC */
+#define DESC_NUM 512 /* Max number of descriptors in the descriptor
+ memory (invariant) */
+#define QUEUE_DESC_NUM (DESC_NUM / QUEUE_NUM) /* Number of descriptors per queue */
+#define MAC_ADDR_NUM 32 /* Number of MAC addresses */
+
+#define TX_RING_SIZE (QUEUE_DESC_NUM / 2) /* Must be a power of 2 */
+#define RX_RING_SIZE (QUEUE_DESC_NUM - TX_RING_SIZE)
+#define RX_RING_MOD_MAX (RX_RING_SIZE - 1)
+#define TX_RING_MOD_MASK (TX_RING_SIZE - 1)
+
+#define PKT_MTU_CRC (ETH_FRAME_LEN + 4)
+#define PKT_MTU_NOCRC ETH_FRAME_LEN
+
+#define TX_TIMEOUT (2*HZ)
+#define EMAC_TIMER_PERIOD (HZ/10)
+
+#define GEMAC_RESET_COLD 1
+#define GEMAC_RESET_WARM 2
+
+#define IDX_TO_CHAN(i) (i) /* Convert index to channel */
+#define IDX_TO_MAC(i) ((i) << 1) /* Convert index to MAC addr offset */
+#define DEV_TO_MAC(d) ((d) * CORE_NUM) /* Convert dev_id to MAC addr offset */
+
+/*
+ * EMAC descriptor
+ */
+struct emac_desc {
+ struct emac_desc *next;
+ u8 *buff;
+ u32 buff_offset_len;
+ u32 packet_flags_len;
+};
+
+/*
+ * Private EMAC information
+ */
+struct emac_private {
+ struct sk_buff *tx_skbuff[TX_RING_SIZE]; /* software TX skbuff ring */
+ struct sk_buff *rx_skbuff[RX_RING_SIZE]; /* software RX skbuff ring */
+ unsigned long skb_cur;
+ unsigned long skb_tx_dirty;
+ unsigned long skb_rx_dirty;
+ unsigned long count_tx;
+
+ struct emac_desc *rx_desc_base;
+ struct emac_desc *tx_desc_base; /* address of rx and tx buffers base */
+ struct emac_desc *cur_rx;
+ struct emac_desc *cur_tx; /* the next free ring entries */
+ struct emac_desc *dirty_tx; /* the ring entry to be freed */
+ struct emac_desc *head_tx; /* the new list head to be sent */
+
+ struct net_device *dev;
+
+ unsigned long mode_flags;
+ unsigned long slave;
+ unsigned long packet_mtu;
+ unsigned long tx_full;
+ unsigned long fatal_error;
+ spinlock_t lock;
+ unsigned long emac_reg_base;
+ unsigned long ectl_reg_base;
+ unsigned long emac_dsc_base;
+ unsigned long mdio_reg_base;
+#ifdef EMAC_HAS_ALE_SUPPORT
+ unsigned int mcast_valid_len;
+ unsigned int *mcast_infos;
+#endif
+};
+
+/*
+ * EMAC Configuration information
+ */
+struct emac_config {
+ u32 flags;
+ u32 enetaddr[6];
+};
+
+#define emac_setbit_reg(reg, val) \
+ (*((volatile u32 *) (ep->emac_reg_base + (reg))) |= (u32) (val))
+
+#define emac_clearbit_reg(reg, val) \
+ (*((volatile u32 *) (ep->emac_reg_base + (reg))) &= ~((u32) (val)))
+
+#define emac_set_reg(reg, val) \
+ (*((volatile u32 *) (ep->emac_reg_base + (reg))) = (u32) (val))
+
+#define emac_get_reg(reg) \
+ (*((volatile u32 *) (ep->emac_reg_base + (reg))))
+
+#define emac_addr_reg(reg) \
+ ((volatile u32 *) (ep->emac_reg_base + (reg)))
+
+#define emac_set_stat(w, reg) \
+ do { \
+ u32 stat = emac_get_reg(reg); \
+ emac_set_reg(reg, stat); \
+ stat += (w); \
+ (w) = stat; \
+ } while (0)
+
+#if defined(CONFIG_SOC_TMS320C6457) || defined(CONFIG_SOC_TMS320C6472) || defined(CONFIG_SOC_TMS320C6474)
+#define ectl_setbit_reg(reg, val) \
+ (*((volatile u32 *) (ep->ectl_reg_base + (reg))) |= (u32) (val))
+
+#define ectl_clearbit_reg(reg, val) \
+ (*((volatile u32 *) (ep->ectl_reg_base + (reg))) &= ~((u32) (val)))
+
+#define ectl_set_reg(reg, val) \
+ (*((volatile u32 *) (ep->ectl_reg_base + (reg))) = (u32) (val))
+
+#define ectl_get_reg(reg) \
+ (*((volatile u32 *) (ep->ectl_reg_base + (reg))))
+
+/* Value for interrupt pacing: (CPUCLK/6) / 250000 (1/4us) = 0x29a on 1GHz DSP */
+#define gemac_int_prescaler() \
+ ((c6x_core_freq / 6) / 250000)
+
+#endif /* defined(CONFIG_SOC_TMS320C6457) || defined(CONFIG_SOC_TMS320C6472) || defined(CONFIG_SOC_TMS320C6474) */
+
+#include <mach/gemac.h>
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_C6X_EMAC_H */
diff --git a/arch/c6x/include/asm/gmdio.h b/arch/c6x/include/asm/gmdio.h
new file mode 100644
index 0000000..af0b177
--- /dev/null
+++ b/arch/c6x/include/asm/gmdio.h
@@ -0,0 +1,217 @@
+/*
+ * linux/include/asm-c6x/gmdio.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Nicolas Videau ([email protected])
+ *
+ * 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_C6X_GMDIO_H
+#define _ASM_C6X_GMDIO_H
+
+#ifdef __KERNEL__
+#include <mach/dscr.h>
+#include <mach/gmdio.h>
+
+#define MDIO_VERSION 0x000 /* Module Version Register */
+#define MDIO_CONTROL 0x004 /* Module Control Register */
+#define MDIO_ALIVE 0x008 /* PHY "Alive" Indication Register */
+#define MDIO_LINK 0x00c /* PHY Link Status Register */
+#define MDIO_LINKINTRAW 0x010 /* Link Status Change Interrupt Register */
+#define MDIO_LINKINTMASKED 0x014 /* Link Status Change Interrupt Register (Masked) */
+#define MDIO_USERINTRAW 0x020 /* User Command Complete Interrupt */
+#define MDIO_USERINTMASKED 0x024 /* User Command Complete Interrupt (Masked) */
+#define MDIO_USERINTMASKSET 0x028 /* Enable User Command Complete Interrupt Mask */
+#define MDIO_USERINTMASKCLEAR 0x02c /* Disable User Command Complete Interrupt Mask */
+#define MDIO_USERACCESS0 0x080 /* User Access Register 0 */
+#define MDIO_USERPHYSEL0 0x084 /* User PHY Select Register 0 */
+#define MDIO_USERACCESS1 0x088 /* User Access Register 1 */
+#define MDIO_USERPHYSEL1 0x08c /* User PHY Select Register 1 */
+
+#define EMAC_M_CLKDIV ((1 << 16) - 1)
+
+#define EMAC_B_FAULTENB (1 << 18)
+#define EMAC_B_FAULT (1 << 19)
+#define EMAC_B_PREAMBLE (1 << 20)
+#define EMAC_B_ENABLE (1 << 30)
+#define EMAC_B_IDLE (1 << 31)
+
+#define MDIO_B_ACK (1 << 29)
+#define MDIO_B_WRITE (1 << 30)
+#define MDIO_B_GO (1 << 31) /* for USERACESS */
+
+#define mdio_setbit_reg(reg, val) \
+ (*((volatile u32 *) (MDIO_REG_BASE + (reg))) |= (u32) (val))
+
+#define mdio_clearbit_reg(reg, val) \
+ (*((volatile u32 *) (MDIO_REG_BASE + (reg))) &= ~((u32) (val)))
+
+#define mdio_set_reg(reg, val) \
+ (*((volatile u32 *) (MDIO_REG_BASE + (reg))) = (u32) (val))
+
+#define mdio_get_reg(reg) \
+ (*((volatile u32 *) (MDIO_REG_BASE + (reg))))
+
+#define mdio_addr_reg(reg) \
+ ((volatile u32 *) (MDIO_REG_BASE + (reg)))
+
+
+/*
+ * MDIO status
+ */
+struct mdio_status {
+ unsigned int mode;
+ unsigned int phy_state;
+ unsigned int phy_ticks;
+ unsigned int phy_addr;
+ unsigned int pending_status;
+ unsigned int link_status;
+ unsigned int macsel;
+ unsigned int emac_txidver;
+};
+
+/*
+ * MDIO events
+ */
+#define MDIO_EVENT_NOCHANGE 0 /* No change from previous status */
+#define MDIO_EVENT_LINKDOWN 1 /* Link down event */
+#define MDIO_EVENT_LINKUP 2 /* Link (or re-link) event */
+#define MDIO_EVENT_PHYERROR 3 /* No PHY connected */
+
+/*
+ * MDIO link status values
+ */
+#define MDIO_LINKSTATUS_NOLINK 0
+#define MDIO_LINKSTATUS_HD10 1
+#define MDIO_LINKSTATUS_FD10 2
+#define MDIO_LINKSTATUS_HD100 3
+#define MDIO_LINKSTATUS_FD100 4
+#define MDIO_LINKSTATUS_FD1000 5
+
+/*
+ * MDIO configuration mode flags
+ */
+#define MDIO_MODE_AUTONEG 0x0001 /* Use Autonegotiate */
+#define MDIO_MODE_HD10 0x0002 /* Use 10Mb/s Half Duplex */
+#define MDIO_MODE_FD10 0x0004 /* Use 10Mb/s Full Duplex */
+#define MDIO_MODE_HD100 0x0008 /* Use 100Mb/s Half Duplex */
+#define MDIO_MODE_FD100 0x0010 /* Use 100Mb/s Full Duplex */
+#define MDIO_MODE_FD1000 0x0020 /* Use 1000Mb/s Full Duplex */
+#define MDIO_MODE_LOOPBACK 0x0040 /* Use PHY Loopback */
+#define MDIO_MODE_NWAYACTIVE 0x0080 /* NWAY is currently active */
+#define MDIO_MODE_EXTLOOPBACK 0x0100 /* Use external PHY Loopback */
+
+/*
+ * MDIO states in the PHY state machine
+ */
+#define MDIO_PHY_MDIOINIT 0
+#define MDIO_PHY_RESET 1
+#define MDIO_PHY_NWAYSTART 2
+#define MDIO_PHY_NWAYWAIT 3
+#define MDIO_PHY_LINKWAIT 4
+#define MDIO_PHY_LINKED 5
+
+/*
+ * PHY control registers
+ */
+#define MDIO_PHY_REG_CONTROL 0
+#define MDIO_PHY_REG_STATUS 1
+#define MDIO_PHY_REG_ID1 2
+#define MDIO_PHY_REG_ID2 3
+#define MDIO_PHY_REG_ADVERTISE 4
+#define MDIO_PHY_REG_PARTNER 5
+#define MDIO_PHY_REG_1000CONTROL 9
+#define MDIO_PHY_REG_1000STATUS 0xA
+#define MDIO_PHY_REG_EXTSTATUS 0xF
+#define MDIO_PHY_REG_SHADOW 0x18
+#define MDIO_PHY_REG_ACCESS 0x1C
+
+#define MDIO_PHY_B_SPEEDMSB (1<<6)
+#define MDIO_PHY_B_DUPLEXFULL (1<<8)
+#define MDIO_PHY_B_AUTORESTART (1<<9)
+#define MDIO_PHY_B_ISOLATE (1<<10)
+#define MDIO_PHY_B_POWERDOWN (1<<11)
+#define MDIO_PHY_B_AUTONEGEN (1<<12)
+#define MDIO_PHY_B_SPEEDLSB (1<<13)
+#define MDIO_PHY_B_SPEED100 (1<<13)
+#define MDIO_PHY_B_LOOPBACK (1<<14)
+#define MDIO_PHY_B_RESET (1<<15) /* for CONTROL */
+
+#define MDIO_PHY_B_FD100 (1<<14)
+#define MDIO_PHY_B_HD100 (1<<13)
+#define MDIO_PHY_B_FD10 (1<<12)
+#define MDIO_PHY_B_HD10 (1<<11)
+#define MDIO_PHY_B_EXTSTATUS (1<<8)
+#define MDIO_PHY_B_NOPREAMBLE (1<<6)
+#define MDIO_PHY_B_AUTOCOMPLETE (1<<5)
+#define MDIO_PHY_B_REMOTEFAULT (1<<4)
+#define MDIO_PHY_B_AUTOCAPABLE (1<<3)
+#define MDIO_PHY_B_LINKSTATUS (1<<2)
+#define MDIO_PHY_B_JABBER (1<<1)
+#define MDIO_PHY_B_EXTENDED (1<<0) /* for STATUS */
+
+#define MDIO_PHY_B_NEXTPAGE (1<<15)
+#define MDIO_PHY_B_ACK (1<<14)
+#define MDIO_PHY_B_FAULT (1<<13)
+#define MDIO_PHY_B_PAUSE (1<<10)
+#define MDIO_PHY_B_AFD100 (1<<8)
+#define MDIO_PHY_B_AHD100 (1<<7)
+#define MDIO_PHY_B_AFD10 (1<<6)
+#define MDIO_PHY_B_AHD10 (1<<5)
+#define MDIO_PHY_B_MSGMASK (0x1F)
+#define MDIO_PHY_B_MSG (1<<0) /* for ADVERTISE and PARTNER */
+
+#define MDIO_PHY_ADV_FD1000 (1<<9) /* for 1000CONTROL */
+
+#define MDIO_PHY_PRT_FD1000 (1<<11) /* for 1000STATUS */
+
+#define MDIO_PHY_EXT_FD1000 (1<<13) /* for EXTSTATUS */
+
+#define MDIO_PHY_B_EXTLOOPBACK 0x8400
+#define MDIO_PHY_B_RGMIIMODE 0xF080
+#define MDIO_PHY_B_INBAND 0xF1C7 /* for SHADOW */
+
+#define MDIO_PHY_B_COPPER 0xFC00 /* for ACCESS */
+
+
+#define mdio_phy_read(regadr, phyadr) \
+ mdio_set_reg(MDIO_USERACCESS0, MDIO_B_GO | \
+ ((phyadr & 0x1f) << 16) | \
+ ((regadr & 0x1f) << 21))
+
+#define mdio_phy_write(regadr, phyadr, data) \
+ mdio_set_reg(MDIO_USERACCESS0, MDIO_B_GO | \
+ MDIO_B_WRITE | \
+ ((phyadr & 0x1f) << 16) | \
+ ((regadr & 0x1f) << 21) | \
+ ((data & 0xffff)))
+
+#define mdio_phy_wait() \
+ while (mdio_get_reg(MDIO_USERACCESS0) & MDIO_B_GO)
+
+#define mdio_phy_wait_res(results) \
+ do { \
+ while (mdio_get_reg(MDIO_USERACCESS0) & MDIO_B_GO) \
+ ; \
+ results = mdio_get_reg(MDIO_USERACCESS0) & 0xffff; \
+ } while (0)
+
+#define mdio_phy_wait_res_ack(results, ack) \
+ do { \
+ while (mdio_get_reg(MDIO_USERACCESS0) & MDIO_B_GO) \
+ ; \
+ results = mdio_get_reg(MDIO_USERACCESS0) & 0xffff; \
+ ack = (mdio_get_reg(MDIO_USERACCESS0) & MDIO_B_ACK) >> 29; \
+ } while (0)
+
+extern int mdio_init(unsigned int txid_version);
+extern unsigned int mdio_get_status(void);
+extern unsigned int mdio_timer_tick(void);
+extern unsigned int mdio_get_macsel(void);
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_C6X_GMDIO_H */
diff --git a/arch/c6x/include/asm/hardirq.h b/arch/c6x/include/asm/hardirq.h
new file mode 100644
index 0000000..19c4a56
--- /dev/null
+++ b/arch/c6x/include/asm/hardirq.h
@@ -0,0 +1,22 @@
+/*
+ * linux/include/asm-c6x/hardirq.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_HARDIRQ_H
+#define _ASM_C6X_HARDIRQ_H
+
+extern void ack_bad_irq(int irq);
+#define ack_bad_irq ack_bad_irq
+
+#include <asm-generic/hardirq.h>
+
+#endif /* _ASM_C6X_HARDIRQ_H */
diff --git a/arch/c6x/include/asm/hardware.h b/arch/c6x/include/asm/hardware.h
new file mode 100644
index 0000000..69db640
--- /dev/null
+++ b/arch/c6x/include/asm/hardware.h
@@ -0,0 +1,21 @@
+/*
+ * linux/include/asm-c6x/hardware.h
+ *
+ * Port on Texas Instruments TMS320C6x/C6x+ architecture
+ *
+ * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_HARDWARE_H
+#define _ASM_C6X_HARDWARE_H
+
+#define __SYSREG(ADDR, TYPE) (*(volatile TYPE*)(ADDR))
+#define __SYSREGA(ADDR, TYPE) ((volatile TYPE*)(ADDR))
+
+#include <mach/hardware.h>
+
+#endif /* _ASM_C6X_HARDWARE_H */
diff --git a/arch/c6x/include/asm/hw_irq.h b/arch/c6x/include/asm/hw_irq.h
new file mode 100644
index 0000000..7c159eb
--- /dev/null
+++ b/arch/c6x/include/asm/hw_irq.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_HW_IRQ_H
+#define _ASM_C6X_HW_IRQ_H
+
+#include <asm-generic/hw_irq.h>
+
+#endif /* _ASM_C6X_HW_IRQ_H */
diff --git a/arch/c6x/include/asm/io.h b/arch/c6x/include/asm/io.h
new file mode 100644
index 0000000..e7a0353
--- /dev/null
+++ b/arch/c6x/include/asm/io.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_IO_H
+#define _ASM_C6X_IO_H
+
+#include <asm-generic/io.h>
+
+#endif /* _ASM_C6X_IO_H */
diff --git a/arch/c6x/include/asm/ioctl.h b/arch/c6x/include/asm/ioctl.h
new file mode 100644
index 0000000..53fd15e
--- /dev/null
+++ b/arch/c6x/include/asm/ioctl.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_IOCTL_H
+#define _ASM_C6X_IOCTL_H
+
+#include <asm-generic/ioctl.h>
+
+#endif /* _ASM_C6X_IOCTL_H */
diff --git a/arch/c6x/include/asm/ioctls.h b/arch/c6x/include/asm/ioctls.h
new file mode 100644
index 0000000..fd43676
--- /dev/null
+++ b/arch/c6x/include/asm/ioctls.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_IOCTLS_H
+#define _ASM_C6X_IOCTLS_H
+
+#include <asm-generic/ioctls.h>
+
+#endif /* _ASM_C6X_IOCTLS_H */
diff --git a/arch/c6x/include/asm/ipcbuf.h b/arch/c6x/include/asm/ipcbuf.h
new file mode 100644
index 0000000..9f2d5f0
--- /dev/null
+++ b/arch/c6x/include/asm/ipcbuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_IPCBUF_H
+#define _ASM_C6X_IPCBUF_H
+
+#include <asm-generic/ipcbuf.h>
+
+#endif /* _ASM_C6X_IPCBUF_H */
diff --git a/arch/c6x/include/asm/irq.h b/arch/c6x/include/asm/irq.h
new file mode 100644
index 0000000..177f7db
--- /dev/null
+++ b/arch/c6x/include/asm/irq.h
@@ -0,0 +1,101 @@
+/*
+ * linux/include/asm-c6x/irq.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_IRQ_H
+#define _ASM_C6X_IRQ_H
+
+#include <asm/hardware.h>
+#include <asm/percpu.h>
+
+#include <mach/irq.h>
+
+#define irq_canonicalize(irq) (irq)
+
+#ifdef CONFIG_PIC_C64XPLUS
+#define NR_IRQS (NR_SOC_IRQS + NR_BOARD_IRQS)
+#else
+#define NR_IRQS (NR_SYS_IRQS + NR_BOARD_IRQS)
+#endif
+
+/*
+ * Number of C6x interrupt vectors.
+ *
+ * There are 16 vectors. One each is used by Reset and NMI. Two are reserved.
+ * The remaining 12 vectors are used to route SoC interrupt sources. These
+ * interrupt vectors are prioritized with INT4 having the highest priority
+ * and INT15 having the lowest.
+ *
+ * The C64x+ megamodule provides a way to combine SoC IRQ sources into a single
+ * IRQ vector. There are four combined sources, each of which feed into one of
+ * the 12 general interrupt vectors. The remaining 8 vectors can each route a
+ * single SoC interrupt directly.
+ *
+ */
+#define NR_SYS_IRQS 16
+
+/*
+ * Processor interrupt vector definitions
+ * Interrupt sources are prioritized from INT0 (highest) to INT15 (lowest).
+ */
+#define INT0 0 /* RESET */
+#define INT1 1 /* NMI */
+#define INT2 2 /* Reserved */
+#define INT3 3 /* Reserved */
+#define INT4 4 /* level 4 interrupt */
+#define INT5 5 /* level 5 interrupt */
+#define INT6 6 /* level 6 interrupt */
+#define INT7 7 /* level 7 interrupt */
+#define INT8 8 /* level 8 interrupt */
+#define INT9 9 /* level 9 interrupt */
+#define INT10 10 /* level 10 interrupt */
+#define INT11 11 /* level 11 interrupt */
+#define INT12 12 /* level 12 interrupt */
+#define INT13 13 /* level 13 interrupt */
+#define INT14 14 /* level 14 interrupt */
+#define INT15 15 /* level 15 interrupt */
+
+#ifdef CONFIG_PIC_C64XPLUS
+/* holds mapping of hw interrupt number to kernel IRQ number */
+extern uint16_t prio_to_irq[];
+
+#define hw_to_kernel_irq(hw) prio_to_irq[(hw)]
+
+/*
+ * Functions used to map interrupts from one level to another.
+ *
+ * For irq_map:
+ * irq_src is a kernel IRQ number corresponding to megamodule combiner event
+ * irq_dst is a hardware interrupt number (INT4 - INT15)
+ *
+ * For irq_cic_map:
+ * irq_src is a kernel IRQ number corresponding to CIC combiner event
+ * irq_dst is a kernel IRQ number corresponding to megamodule combiner event
+ *
+ * In order to map a CIC event directly to a core hardware interrupt, it must
+ * first be mapped to a megamodule event with irq_cic_map(). Then the megamodule
+ * event can be mapped to a core hardware interrupt with irq_map().
+ *
+ */
+extern void irq_map(unsigned int irq_src, unsigned int irq_dst);
+extern void irq_cic_map(unsigned int irq_src, unsigned int irq_dst);
+extern void cic_raw_map(unsigned int src, unsigned int dst, int core);
+
+extern void __init init_pic_c64xplus(void);
+#endif
+
+extern void init_IRQ(void);
+
+struct pt_regs;
+
+extern asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs);
+
+#endif /* _ASM_C6X_IRQ_H */
diff --git a/arch/c6x/include/asm/irq_regs.h b/arch/c6x/include/asm/irq_regs.h
new file mode 100644
index 0000000..143adfe
--- /dev/null
+++ b/arch/c6x/include/asm/irq_regs.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_IRQ_REGS_H
+#define _ASM_C6X_IRQ_REGS_H
+
+#include <asm-generic/irq_regs.h>
+
+#endif /* _ASM_C6X_IRQ_REGS_H */
diff --git a/arch/c6x/include/asm/irqflags.h b/arch/c6x/include/asm/irqflags.h
new file mode 100644
index 0000000..bac497f
--- /dev/null
+++ b/arch/c6x/include/asm/irqflags.h
@@ -0,0 +1,71 @@
+/* C6X IRQ flag handling
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Written by Mark Salter ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public Licence
+ * as published by the Free Software Foundation; either version
+ * 2 of the Licence, or (at your option) any later version.
+ */
+
+#ifndef _ASM_IRQFLAGS_H
+#define _ASM_IRQFLAGS_H
+
+#ifndef __ASSEMBLY__
+
+/* read interrupt enabled status */
+static inline unsigned long arch_local_save_flags(void)
+{
+ unsigned long flags;
+
+ asm volatile (" mvc .s2 CSR,%0\n" : "=b"(flags));
+ return flags;
+}
+
+/* set interrupt enabled status */
+static inline void arch_local_irq_restore(unsigned long flags)
+{
+ asm volatile (" mvc .s2 %0,CSR\n" : : "b"(flags));
+}
+
+/* unconditionally enable interrupts */
+static inline void arch_local_irq_enable(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ flags |= 1;
+ arch_local_irq_restore(flags);
+}
+
+/* unconditionally disable interrupts */
+static inline void arch_local_irq_disable(void)
+{
+ unsigned long flags = arch_local_save_flags();
+ flags &= ~1;
+ arch_local_irq_restore(flags);
+}
+
+/* get status and disable interrupts */
+static inline unsigned long arch_local_irq_save(void)
+{
+ unsigned long flags;
+
+ flags = arch_local_save_flags();
+ arch_local_irq_restore(flags & ~1);
+ return flags;
+}
+
+/* test flags */
+static inline int arch_irqs_disabled_flags(unsigned long flags)
+{
+ return (flags & 1) == 0;
+}
+
+/* test hardware interrupt enable bit */
+static inline int arch_irqs_disabled(void)
+{
+ return arch_irqs_disabled_flags(arch_local_save_flags());
+}
+
+#endif /* __ASSEMBLY__ */
+#endif /* __ASM_IRQFLAGS_H */
diff --git a/arch/c6x/include/asm/kdebug.h b/arch/c6x/include/asm/kdebug.h
new file mode 100644
index 0000000..d2c70ad
--- /dev/null
+++ b/arch/c6x/include/asm/kdebug.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_KDEBUG_H
+#define _ASM_C6X_KDEBUG_H
+
+#include <asm-generic/kdebug.h>
+
+#endif /* _ASM_C6X_KDEBUG_H */
diff --git a/arch/c6x/include/asm/kmap_types.h b/arch/c6x/include/asm/kmap_types.h
new file mode 100644
index 0000000..696057f
--- /dev/null
+++ b/arch/c6x/include/asm/kmap_types.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_KMAP_TYPES_H
+#define _ASM_C6X_KMAP_TYPES_H
+
+#include <asm-generic/kmap_types.h>
+
+#endif /* _ASM_C6X_KMAP_TYPES_H */
diff --git a/arch/c6x/include/asm/leds.h b/arch/c6x/include/asm/leds.h
new file mode 100644
index 0000000..bdd17da
--- /dev/null
+++ b/arch/c6x/include/asm/leds.h
@@ -0,0 +1,22 @@
+/*
+ * arch/c6x/include/asm/leds.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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_C6X_LEDS_H
+#define _ASM_C6X_LEDS_H
+
+#include <mach/board.h>
+
+#ifndef __ASSEMBLY__
+extern void c6x_arch_idle_led(int state);
+#endif
+
+#endif /* _ASM_C6X_LEDS_H */
diff --git a/arch/c6x/include/asm/linkage.h b/arch/c6x/include/asm/linkage.h
new file mode 100644
index 0000000..d6807e9
--- /dev/null
+++ b/arch/c6x/include/asm/linkage.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_LINKAGE_H
+#define _ASM_C6X_LINKAGE_H
+
+#include <asm-generic/linkage.h>
+
+#endif /* _ASM_C6X_LINKAGE_H */
diff --git a/arch/c6x/include/asm/local.h b/arch/c6x/include/asm/local.h
new file mode 100644
index 0000000..17a94b4
--- /dev/null
+++ b/arch/c6x/include/asm/local.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_LOCAL_H
+#define _ASM_C6X_LOCAL_H
+
+#include <asm-generic/local.h>
+
+#endif /* _ASM_C6X_LOCAL_H */
diff --git a/arch/c6x/include/asm/mman.h b/arch/c6x/include/asm/mman.h
new file mode 100644
index 0000000..8234838
--- /dev/null
+++ b/arch/c6x/include/asm/mman.h
@@ -0,0 +1,7 @@
+#ifndef _ASM_C6X_MMAN_H
+#define _ASM_C6X_MMAN_H
+
+#include <asm-generic/mman.h>
+
+#endif /* _ASM_C6X_MMAN_H */
+
diff --git a/arch/c6x/include/asm/mmu.h b/arch/c6x/include/asm/mmu.h
new file mode 100644
index 0000000..8d376e9
--- /dev/null
+++ b/arch/c6x/include/asm/mmu.h
@@ -0,0 +1,20 @@
+/*
+ * linux/include/asm-c6x/mmu.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_MMU_H
+#define _ASM_C6X_MMU_H
+
+typedef struct {
+ unsigned long end_brk;
+} mm_context_t;
+
+#endif /* _ASM_C6X_MMU_H */
diff --git a/arch/c6x/include/asm/mmu_context.h b/arch/c6x/include/asm/mmu_context.h
new file mode 100644
index 0000000..7b222ba
--- /dev/null
+++ b/arch/c6x/include/asm/mmu_context.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_MMU_CONTEXT_H
+#define _ASM_C6X_MMU_CONTEXT_H
+
+#include <asm-generic/mmu_context.h>
+
+#endif /* _ASM_C6X_MMU_CONTEXT_H */
diff --git a/arch/c6x/include/asm/module.h b/arch/c6x/include/asm/module.h
new file mode 100644
index 0000000..d76d106
--- /dev/null
+++ b/arch/c6x/include/asm/module.h
@@ -0,0 +1,35 @@
+/*
+ * arch/c6x/include/asm/module.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Updated for 2.6.34 by: Mark Salter ([email protected])
+ *
+ * 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_C6X_MODULE_H
+#define _ASM_C6X_MODULE_H
+
+#define Elf_Shdr Elf32_Shdr
+#define Elf_Sym Elf32_Sym
+#define Elf_Ehdr Elf32_Ehdr
+#define Elf_Addr Elf32_Addr
+#define Elf_Word Elf32_Word
+
+/*
+ * This file contains the C6x architecture specific module code.
+ */
+struct mod_arch_specific {
+};
+
+struct loaded_sections {
+ unsigned int new_vaddr;
+ unsigned int loaded;
+};
+
+#endif /* _ASM_C6X_MODULE_H */
diff --git a/arch/c6x/include/asm/msgbuf.h b/arch/c6x/include/asm/msgbuf.h
new file mode 100644
index 0000000..14f063e
--- /dev/null
+++ b/arch/c6x/include/asm/msgbuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_MSGBUF_H
+#define _ASM_C6X_MSGBUF_H
+
+#include <asm-generic/msgbuf.h>
+
+#endif /* _ASM_C6X_MSGBUF_H */
diff --git a/arch/c6x/include/asm/mutex.h b/arch/c6x/include/asm/mutex.h
new file mode 100644
index 0000000..7a7248e
--- /dev/null
+++ b/arch/c6x/include/asm/mutex.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_MUTEX_H
+#define _ASM_C6X_MUTEX_H
+
+#include <asm-generic/mutex-null.h>
+
+#endif /* _ASM_C6X_MUTEX_H */
diff --git a/arch/c6x/include/asm/page.h b/arch/c6x/include/asm/page.h
new file mode 100644
index 0000000..d18e2b0
--- /dev/null
+++ b/arch/c6x/include/asm/page.h
@@ -0,0 +1,11 @@
+#ifndef _ASM_C6X_PAGE_H
+#define _ASM_C6X_PAGE_H
+
+#define VM_DATA_DEFAULT_FLAGS \
+ (VM_READ | VM_WRITE | \
+ ((current->personality & READ_IMPLIES_EXEC) ? VM_EXEC : 0) | \
+ VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
+
+#include <asm-generic/page.h>
+
+#endif /* _ASM_C6X_PAGE_H */
diff --git a/arch/c6x/include/asm/param.h b/arch/c6x/include/asm/param.h
new file mode 100644
index 0000000..986e6c5
--- /dev/null
+++ b/arch/c6x/include/asm/param.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_PARAM_H
+#define _ASM_C6X_PARAM_H
+
+#include <asm-generic/param.h>
+
+#endif /* _ASM_C6X_PARAM_H */
diff --git a/arch/c6x/include/asm/pci.h b/arch/c6x/include/asm/pci.h
new file mode 100644
index 0000000..d7da231
--- /dev/null
+++ b/arch/c6x/include/asm/pci.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_PCI_H
+#define _ASM_C6X_PCI_H
+
+#include <asm-generic/pci.h>
+
+#endif /* _ASM_C6X_PCI_H */
diff --git a/arch/c6x/include/asm/percpu.h b/arch/c6x/include/asm/percpu.h
new file mode 100644
index 0000000..dbb7dc5
--- /dev/null
+++ b/arch/c6x/include/asm/percpu.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_PERCPU_H
+#define _ASM_C6X_PERCPU_H
+
+#include <asm-generic/percpu.h>
+
+#endif /* _ASM_C6X_PERCPU_H */
diff --git a/arch/c6x/include/asm/pgalloc.h b/arch/c6x/include/asm/pgalloc.h
new file mode 100644
index 0000000..aff53f7
--- /dev/null
+++ b/arch/c6x/include/asm/pgalloc.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_PGALLOC_H
+#define _ASM_C6X_PGALLOC_H
+
+#include <asm-generic/pgalloc.h>
+
+#endif /* _ASM_C6X_PGALLOC_H */
diff --git a/arch/c6x/include/asm/pgtable.h b/arch/c6x/include/asm/pgtable.h
new file mode 100644
index 0000000..4e849d7
--- /dev/null
+++ b/arch/c6x/include/asm/pgtable.h
@@ -0,0 +1,83 @@
+/*
+ * linux/include/asm-c6x/pgtable.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_PGTABLE_H
+#define _ASM_C6X_PGTABLE_H
+
+#include <asm-generic/4level-fixup.h>
+
+#include <asm/setup.h>
+#include <asm/page.h>
+
+/*
+ * All 32bit addresses are effectively valid for vmalloc...
+ * Sort of meaningless for non-VM targets.
+ */
+#define VMALLOC_START 0
+#define VMALLOC_END 0xffffffff
+
+#define pgd_present(pgd) (1)
+#define pgd_none(pgd) (0)
+#define pgd_bad(pgd) (0)
+#define pgd_clear(pgdp)
+#define kern_addr_valid(addr) (1)
+
+#define pmd_offset(a, b) ((void *)0)
+#define pmd_none(x) (!pmd_val(x))
+#define pmd_present(x) (pmd_val(x))
+#define pmd_clear(xp) do { set_pmd(xp, __pmd(0)); } while (0)
+#define pmd_bad(x) (pmd_val(x) & ~PAGE_MASK)
+
+#define PAGE_NONE __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_SHARED __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_COPY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_READONLY __pgprot(0) /* these mean nothing to NO_MM */
+#define PAGE_KERNEL __pgprot(0) /* these mean nothing to NO_MM */
+#define pgprot_noncached(prot) (prot)
+
+extern void paging_init(void);
+
+#define __swp_type(x) (0)
+#define __swp_offset(x) (0)
+#define __swp_entry(typ, off) ((swp_entry_t) { ((typ) | ((off) << 7)) })
+#define __pte_to_swp_entry(pte) ((swp_entry_t) { pte_val(pte) })
+#define __swp_entry_to_pte(x) ((pte_t) { (x).val })
+
+static inline int pte_file(pte_t pte)
+{
+ return 0;
+}
+
+#define set_pte(pteptr, pteval) (*(pteptr) = pteval)
+#define set_pte_at(mm, addr, ptep, pteval) set_pte(ptep, pteval)
+
+/*
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+#define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
+extern unsigned long empty_zero_page;
+
+#define swapper_pg_dir ((pgd_t *) 0)
+
+/*
+ * No page table caches to initialise
+ */
+#define pgtable_cache_init() do { } while (0)
+#define io_remap_pfn_range remap_pfn_range
+
+#define io_remap_page_range(vma, vaddr, paddr, size, prot) \
+ remap_pfn_range(vma, vaddr, (paddr) >> PAGE_SHIFT, size, prot)
+
+#include <asm-generic/pgtable.h>
+
+#endif /* _ASM_C6X_PGTABLE_H */
diff --git a/arch/c6x/include/asm/pll.h b/arch/c6x/include/asm/pll.h
new file mode 100644
index 0000000..86bcdd8
--- /dev/null
+++ b/arch/c6x/include/asm/pll.h
@@ -0,0 +1,79 @@
+/*
+ * linux/include/asm-c6x/pll.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Nicolas Videau ([email protected])
+ *
+ * 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_C6X_PLL_H
+#define _ASM_C6X_PLL_H
+
+#include <asm/io.h>
+#include <mach/pll.h>
+
+#ifdef ARCH_PLL1_BASE
+#define pll1_set_reg(reg, val) \
+ (*(volatile unsigned long *)(ARCH_PLL1_BASE + (reg)) = (val))
+
+#define pll1_get_reg(reg) \
+ (*(volatile unsigned long *)(ARCH_PLL1_BASE + (reg)))
+
+#define pll1_clearbit_reg(reg, val) \
+ pll1_set_reg((reg), pll1_get_reg(reg) & ~((u32)(val)))
+
+#define pll1_setbit_reg(reg, val) \
+ pll1_set_reg((reg), pll1_get_reg(reg) | (u32)(val))
+
+static inline void pll1_wait_gostat(void)
+{
+ while (pll1_get_reg(PLLSTAT) & PLLSTAT_GOSTAT)
+ ;
+}
+#endif /* ARCH_PLL1_BASE */
+
+#ifdef ARCH_PLL2_BASE
+#define pll2_set_reg(reg, val) \
+ (*(volatile unsigned long *)(ARCH_PLL2_BASE + (reg)) = (val))
+
+#define pll2_get_reg(reg) \
+ (*(volatile unsigned long *)(ARCH_PLL2_BASE + (reg)))
+
+#define pll2_clearbit_reg(reg, val) \
+ pll2_set_reg((reg), pll2_get_reg(reg) & ~((u32)(val)))
+
+#define pll2_setbit_reg(reg, val) \
+ pll2_set_reg((reg), pll2_get_reg(reg) | (u32)(val))
+
+static inline void pll2_wait_gostat(void)
+{
+ while (pll2_get_reg(PLLSTAT) & PLLSTAT_GOSTAT)
+ ;
+}
+#endif /* ARCH_PLL2_BASE */
+
+#ifdef ARCH_PLL3_BASE
+#define pll3_set_reg(reg, val) \
+ (*(volatile unsigned long *)(ARCH_PLL3_BASE + (reg)) = (val))
+
+#define pll3_get_reg(reg) \
+ (*(volatile unsigned long *)(ARCH_PLL3_BASE + (reg)))
+
+#define pll3_clearbit_reg(reg, val) \
+ pll3_set_reg((reg), pll3_get_reg(reg) & ~((u32)(val)))
+
+#define pll3_setbit_reg(reg, val) \
+ pll3_set_reg((reg), pll3_get_reg(reg) | (u32)(val))
+
+static inline void pll3_wait_gostat(void)
+{
+ while (pll3_get_reg(PLLSTAT) & PLLSTAT_GOSTAT)
+ ;
+}
+#endif /* ARCH_PLL2_BASE */
+
+#endif /*_ASM_C6X_PLL_H */
diff --git a/arch/c6x/include/asm/pm.h b/arch/c6x/include/asm/pm.h
new file mode 100644
index 0000000..1bc387f
--- /dev/null
+++ b/arch/c6x/include/asm/pm.h
@@ -0,0 +1,48 @@
+/*
+ * linux/include/asm-c6x/pm.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_PM_H
+#define _ASM_C6X_PM_H
+
+#define PWRD_NONE 0x00
+#define PWRD_PD1A 0x09
+#define PWRD_PD1B 0x11
+#define PWRD_PD2 0x1a
+#define PWRD_PD3 0x1c
+#define PWRD_IDLE 0xff
+
+#define pwrd_set(pwrd) or_creg(CSR, ((pwrd) & 0xff) << 10))
+#define do_idle() asm(" IDLE\n")
+
+#define PWR_PDCTL_BASE 0x019c0200
+
+#define PWR_PDCTL_MCBSP2 0x10
+#define PWR_PDCTL_MCBSP1 0x08
+#define PWR_PDCTL_MCBSP0 0x04
+#define PWR_PDCTL_EMIF 0x02
+#define PWR_PDCTL_DMA 0x01
+#define PWR_PDCTL_ALL 0x1f
+
+#define pwr_pdctl_setbit(val) \
+ (*((volatile unsigned int *) PWR_PDCTL_BASE) |= (unsigned int) (val))
+
+#define pwr_pdctl_clearbit(val) \
+ (*((volatile unsigned int *) PWR_PDCTL_BASE) &= ~((unsigned int) (val)))
+
+#define pwr_pdctl_set(val) \
+ (*((volatile unsigned int *) PWR_PDCTL_BASE) = (unsigned int) (val))
+
+#define pwr_pdctl_get() \
+ (*((volatile unsigned int *) PWR_PDCTL_BASE))
+
+#endif /* _ASM_C6X_PM_H */
+
diff --git a/arch/c6x/include/asm/poll.h b/arch/c6x/include/asm/poll.h
new file mode 100644
index 0000000..2d5834e
--- /dev/null
+++ b/arch/c6x/include/asm/poll.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_POLL_H
+#define _ASM_C6X_POLL_H
+
+#include <asm-generic/poll.h>
+
+#endif /* _ASM_C6X_POLL_H */
diff --git a/arch/c6x/include/asm/posix_types.h b/arch/c6x/include/asm/posix_types.h
new file mode 100644
index 0000000..3585157
--- /dev/null
+++ b/arch/c6x/include/asm/posix_types.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_POSIX_TYPES_H
+#define _ASM_C6X_POSIX_TYPES_H
+
+#include <asm-generic/posix_types.h>
+
+#endif /* _ASM_C6X_POSIX_TYPES_H */
diff --git a/arch/c6x/include/asm/processor.h b/arch/c6x/include/asm/processor.h
new file mode 100644
index 0000000..bb5678d
--- /dev/null
+++ b/arch/c6x/include/asm/processor.h
@@ -0,0 +1,118 @@
+/*
+ * linux/include/asm-c6x/processor.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Updated for 2.6.34: Mark Salter <[email protected]>
+ *
+ * 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_C6X_PROCESSOR_H
+#define _ASM_C6X_PROCESSOR_H
+
+#include <asm/ptrace.h>
+#include <asm/page.h>
+#include <asm/current.h>
+
+/*
+ * Default implementation of macro that returns current
+ * instruction pointer ("program counter").
+ */
+#define current_text_addr() \
+({ \
+ void *__pc; \
+ asm("mvc .S2 pce1,%0\n" : "=b"(__pc)); \
+ __pc; \
+})
+
+/*
+ * User space process size. Meaningless for NOMMU.
+ */
+#define TASK_SIZE 0xFFFFFFFF
+
+/*
+ * This decides where the kernel will search for a free chunk of vm
+ * space during mmap's. We won't be using it
+ */
+#define TASK_UNMAPPED_BASE 0
+
+struct thread_struct {
+ unsigned long long b15_14;
+ unsigned long long a15_14;
+ unsigned long long b13_12;
+ unsigned long long a13_12;
+ unsigned long long b11_10;
+ unsigned long long a11_10;
+ unsigned long long ricl_icl;
+ unsigned long usp; /* user stack pointer */
+ unsigned long pc; /* kernel pc */
+ unsigned long wchan;
+};
+
+#define INIT_THREAD \
+{ \
+ .usp = 0, \
+ .wchan = 0, \
+}
+
+#define INIT_MMAP { \
+ &init_mm, 0, 0, NULL, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, 1, \
+ NULL, NULL }
+
+#define task_pt_regs(task) \
+ ((struct pt_regs *)(THREAD_START_SP + task_stack_page(task)) - 1)
+
+#define alloc_kernel_stack() __get_free_page(GFP_KERNEL)
+#define free_kernel_stack(page) free_page((page))
+
+
+/* Forward declaration, a strange C thing */
+struct task_struct;
+
+extern void start_thread(struct pt_regs *regs, unsigned int pc,
+ unsigned long usp);
+
+/* Free all resources held by a thread. */
+static inline void release_thread(struct task_struct *dead_task)
+{
+}
+
+/* Prepare to copy thread state - unlazy all lazy status */
+#define prepare_to_copy(tsk) do { } while (0)
+
+extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
+
+#define copy_segments(tsk, mm) do { } while (0)
+#define release_segments(mm) do { } while (0)
+
+/*
+ * saved PC of a blocked thread.
+ */
+#define thread_saved_pc(tsk) (task_pt_regs(tsk)->pc)
+
+/*
+ * saved kernel SP of a blocked thread.
+ */
+#ifdef _BIG_ENDIAN
+#define thread_saved_ksp(tsk) \
+ (*(unsigned long *)&(tsk)->thread.b15_14)
+#else
+#define thread_saved_ksp(tsk) \
+ (*(((unsigned long *)&(tsk)->thread.b15_14) + 1))
+#endif
+
+extern unsigned long get_wchan(struct task_struct *p);
+
+#define KSTK_EIP(tsk) (task_pt_regs(task)->pc)
+#define KSTK_ESP(tsk) (task_pt_regs(task)->sp)
+
+#define cpu_relax() do { } while (0)
+
+extern const struct seq_operations cpuinfo_op;
+
+#endif /* ASM_C6X_PROCESSOR_H */
diff --git a/arch/c6x/include/asm/procinfo.h b/arch/c6x/include/asm/procinfo.h
new file mode 100644
index 0000000..b9937ef
--- /dev/null
+++ b/arch/c6x/include/asm/procinfo.h
@@ -0,0 +1,30 @@
+/*
+ * arch/c6x/include/asm/procinfo.h
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter ([email protected])
+ *
+ *
+ * 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_C6X_PROCINFO_H
+#define _ASM_C6X_PROCINFO_H
+
+#ifdef __KERNEL__
+
+struct proc_info_list {
+ unsigned int cpu_val;
+ unsigned int cpu_mask;
+ const char *arch_name;
+ const char *elf_name;
+ unsigned int elf_hwcap;
+};
+
+#else /* __KERNEL__ */
+#include <asm/elf.h>
+#warning "Please include asm/elf.h instead"
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_C6X_PROCINFO_H */
diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h
new file mode 100644
index 0000000..7e94de8
--- /dev/null
+++ b/arch/c6x/include/asm/ptrace.h
@@ -0,0 +1,186 @@
+/*
+ * linux/include/asm-c6x/ptrace.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Updated for 2.6.34: Mark Salter <[email protected]>
+ *
+ * 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_C6X_PTRACE_H
+#define _ASM_C6X_PTRACE_H
+
+#include <linux/linkage.h>
+
+#if defined(__TMS320C6XPLUS__) || defined(_TMS320C6400_PLUS)
+#define BKPT_OPCODE 0x56454314 /* illegal opcode */
+#else
+#define BKPT_OPCODE 0x0000a122 /* BNOP .S2 0,5 */
+#endif
+
+#ifdef _BIG_ENDIAN
+#define PT_LO(odd, even) odd
+#define PT_HI(odd, even) even
+#else
+#define PT_LO(odd, even) even
+#define PT_HI(odd, even) odd
+#endif
+
+#define PT_A4_ORG PT_LO(1, 0)
+#define PT_TSR PT_HI(1, 0)
+#define PT_ILC PT_LO(3, 2)
+#define PT_RILC PT_HI(3, 2)
+#define PT_CSR PT_LO(5, 4)
+#define PT_PC PT_HI(5, 4)
+#define PT_B16 PT_LO(7, 6)
+#define PT_B17 PT_HI(7, 6)
+#define PT_B18 PT_LO(9, 8)
+#define PT_B19 PT_HI(9, 8)
+#define PT_B20 PT_LO(11, 10)
+#define PT_B21 PT_HI(11, 10)
+#define PT_B22 PT_LO(13, 12)
+#define PT_B23 PT_HI(13, 12)
+#define PT_B24 PT_LO(15, 14)
+#define PT_B25 PT_HI(15, 14)
+#define PT_B26 PT_LO(17, 16)
+#define PT_B27 PT_HI(17, 16)
+#define PT_B28 PT_LO(19, 18)
+#define PT_B29 PT_HI(19, 18)
+#define PT_B30 PT_LO(21, 20)
+#define PT_B31 PT_HI(21, 20)
+#define PT_B0 PT_LO(23, 22)
+#define PT_B1 PT_HI(23, 22)
+#define PT_B2 PT_LO(25, 24)
+#define PT_B3 PT_HI(25, 24)
+#define PT_B4 PT_LO(27, 26)
+#define PT_B5 PT_HI(27, 26)
+#define PT_B6 PT_LO(29, 28)
+#define PT_B7 PT_HI(29, 28)
+#define PT_B8 PT_LO(31, 30)
+#define PT_B9 PT_HI(31, 30)
+#define PT_B10 PT_LO(33, 32)
+#define PT_B11 PT_HI(33, 32)
+#define PT_B12 PT_LO(35, 34)
+#define PT_B13 PT_HI(35, 34)
+#define PT_A16 PT_LO(37, 36)
+#define PT_A17 PT_HI(37, 36)
+#define PT_A18 PT_LO(39, 38)
+#define PT_A19 PT_HI(39, 38)
+#define PT_A20 PT_LO(41, 40)
+#define PT_A21 PT_HI(41, 40)
+#define PT_A22 PT_LO(43, 42)
+#define PT_A23 PT_HI(43, 42)
+#define PT_A24 PT_LO(45, 44)
+#define PT_A25 PT_HI(45, 44)
+#define PT_A26 PT_LO(47, 46)
+#define PT_A27 PT_HI(47, 46)
+#define PT_A28 PT_LO(49, 48)
+#define PT_A29 PT_HI(49, 48)
+#define PT_A30 PT_LO(51, 50)
+#define PT_A31 PT_HI(51, 50)
+#define PT_A0 PT_LO(53, 52)
+#define PT_A1 PT_HI(53, 52)
+#define PT_A2 PT_LO(55, 54)
+#define PT_A3 PT_HI(55, 54)
+#define PT_A4 PT_LO(57, 56)
+#define PT_A5 PT_HI(57, 56)
+#define PT_A6 PT_LO(59, 58)
+#define PT_A7 PT_HI(59, 58)
+#define PT_A8 PT_LO(61, 60)
+#define PT_A9 PT_HI(61, 60)
+#define PT_A10 PT_LO(63, 62)
+#define PT_A11 PT_HI(63, 62)
+#define PT_A12 PT_LO(65, 64)
+#define PT_A13 PT_HI(65, 64)
+#define PT_A14 PT_LO(67, 66)
+#define PT_A15 PT_HI(67, 66)
+#define PT_B14 PT_LO(69, 68)
+#define PT_B15 PT_HI(69, 68)
+
+#define PT_DP PT_B14 /* Data Segment Pointer (B14) */
+#define PT_SP PT_B15 /* Stack Pointer (B15) */
+
+#ifndef __ASSEMBLY__
+
+#ifdef _BIG_ENDIAN
+#define REG_PAIR(odd, even) unsigned long odd; unsigned long even
+#else
+#define REG_PAIR(odd, even) unsigned long even; unsigned long odd
+#endif
+
+/*
+ * this struct defines the way the registers are stored on the
+ * stack during a system call. fields defined with REG_PAIR
+ * are saved and restored using double-word memory operations
+ * which means the word ordering of the pair depends on endianess.
+ */
+struct pt_regs {
+ REG_PAIR(tsr, orig_a4);
+ REG_PAIR(rilc, ilc);
+ REG_PAIR(pc, csr);
+
+ REG_PAIR(b17, b16);
+ REG_PAIR(b19, b18);
+ REG_PAIR(b21, b20);
+ REG_PAIR(b23, b22);
+ REG_PAIR(b25, b24);
+ REG_PAIR(b27, b26);
+ REG_PAIR(b29, b28);
+ REG_PAIR(b31, b30);
+
+ REG_PAIR(b1, b0);
+ REG_PAIR(b3, b2);
+ REG_PAIR(b5, b4);
+ REG_PAIR(b7, b6);
+ REG_PAIR(b9, b8);
+ REG_PAIR(b11, b10);
+ REG_PAIR(b13, b12);
+
+ REG_PAIR(a17, a16);
+ REG_PAIR(a19, a18);
+ REG_PAIR(a21, a20);
+ REG_PAIR(a23, a22);
+ REG_PAIR(a25, a24);
+ REG_PAIR(a27, a26);
+ REG_PAIR(a29, a28);
+ REG_PAIR(a31, a30);
+
+ REG_PAIR(a1, a0);
+ REG_PAIR(a3, a2);
+ REG_PAIR(a5, a4);
+ REG_PAIR(a7, a6);
+ REG_PAIR(a9, a8);
+ REG_PAIR(a11, a10);
+ REG_PAIR(a13, a12);
+
+ REG_PAIR(a15, a14);
+ REG_PAIR(sp, dp);
+};
+
+#define PTRACE_GETREGS 12
+#define PTRACE_SETREGS 13
+#define PTRACE_GETFPREGS 14
+#define PTRACE_SETFPREGS 15
+
+#ifdef __KERNEL__
+
+#define DEFAULT_CSR 0x0001 /* interrupt enable by default */
+ /* used in /include/asm/processor.h*/
+
+#define user_mode(regs) ((((regs)->tsr) & 0x40) != 0)
+
+#define instruction_pointer(regs) ((regs)->pc)
+#define profile_pc(regs) instruction_pointer(regs)
+extern void show_regs(struct pt_regs *);
+
+extern asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs);
+extern asmlinkage void syscall_trace_exit(struct pt_regs *regs);
+
+#endif /* __KERNEL__ */
+#endif /* __ASSEMBLY__ */
+#endif /* _ASM_C6X_PTRACE_H */
diff --git a/arch/c6x/include/asm/resource.h b/arch/c6x/include/asm/resource.h
new file mode 100644
index 0000000..5c18fea
--- /dev/null
+++ b/arch/c6x/include/asm/resource.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_RESOURCE_H
+#define _ASM_C6X_RESOURCE_H
+
+#include <asm-generic/resource.h>
+
+#endif /* _ASM_C6X_RESOURCE_H */
diff --git a/arch/c6x/include/asm/scatterlist.h b/arch/c6x/include/asm/scatterlist.h
new file mode 100644
index 0000000..f4a0622
--- /dev/null
+++ b/arch/c6x/include/asm/scatterlist.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SCATTERLIST_H
+#define _ASM_C6X_SCATTERLIST_H
+
+#include <asm-generic/scatterlist.h>
+
+#endif /* _ASM_C6X_SCATTERLIST_H */
diff --git a/arch/c6x/include/asm/sections.h b/arch/c6x/include/asm/sections.h
new file mode 100644
index 0000000..d26cc45
--- /dev/null
+++ b/arch/c6x/include/asm/sections.h
@@ -0,0 +1,17 @@
+#ifndef _ASM_C6X_SECTIONS_H
+#define _ASM_C6X_SECTIONS_H
+
+#include <asm-generic/sections.h>
+
+extern char _vectors_start[];
+extern char _vectors_end[];
+
+#ifdef CONFIG_MTD_UCLINUX
+extern char _ebss[];
+#endif
+
+#ifdef CONFIG_XIP_KERNEL
+extern char _data_lma[];
+#endif
+
+#endif /* _ASM_C6X_SECTIONS_H */
diff --git a/arch/c6x/include/asm/segment.h b/arch/c6x/include/asm/segment.h
new file mode 100644
index 0000000..f1b81e5
--- /dev/null
+++ b/arch/c6x/include/asm/segment.h
@@ -0,0 +1 @@
+#include <asm-generic/segment.h>
diff --git a/arch/c6x/include/asm/sembuf.h b/arch/c6x/include/asm/sembuf.h
new file mode 100644
index 0000000..77a6b25
--- /dev/null
+++ b/arch/c6x/include/asm/sembuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SEMBUF_H
+#define _ASM_C6X_SEMBUF_H
+
+#include <asm-generic/sembuf.h>
+
+#endif /* _ASM_C6X_SEMBUF_H */
diff --git a/arch/c6x/include/asm/serial.h b/arch/c6x/include/asm/serial.h
new file mode 100644
index 0000000..47bc618
--- /dev/null
+++ b/arch/c6x/include/asm/serial.h
@@ -0,0 +1,25 @@
+/*
+ * linux/include/asm-c6x/serial.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_SERIAL_H
+#define _ASM_C6X_SERIAL_H
+
+#include <mach/board.h>
+
+#ifndef BASE_BAUD
+/*
+ * This assumes you have a 1.8432 MHz clock for your UART.
+ */
+#define BASE_BAUD (1843200 / 16)
+#endif
+
+#endif /* _ASM_C6X_SERIAL_H */
diff --git a/arch/c6x/include/asm/setup.h b/arch/c6x/include/asm/setup.h
new file mode 100644
index 0000000..67c499f
--- /dev/null
+++ b/arch/c6x/include/asm/setup.h
@@ -0,0 +1,49 @@
+/*
+ * linux/include/asm-c6x/setup.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_SETUP_H
+#define _ASM_C6X_SETUP_H
+
+#include <asm/hardware.h>
+
+#define COMMAND_LINE_SIZE 1024
+
+#ifndef __ASSEMBLY__
+
+#ifdef CONFIG_MTD_UCLINUX
+extern struct map_info uclinux_ram_map;
+#endif
+
+#ifdef CONFIG_EARLY_PRINTK
+extern void early_printk(const char *fmt, ...);
+
+#ifdef CONFIG_HVC_C6X
+extern void hvc_c6x_early_puts(const char *buf, unsigned count);
+#endif
+
+#endif /* CONFIG_EARLY_PRINTK */
+
+extern unsigned int c6x_platram_start;
+extern unsigned int c6x_platram_size;
+
+struct tag_header;
+
+extern struct tag_header *c6x_tags_pointer;
+
+extern void c6x_mtd_early_init(void);
+extern void c6x_soc_setup_arch(void);
+extern void c6x_board_setup_arch(void);
+extern char *arch_compute_silicon_rev(u32 silicon_rev);
+extern unsigned int arch_get_silicon_rev(void);
+
+#endif /* !__ASSEMBLY__ */
+#endif /* _ASM_C6X_SETUP_H */
diff --git a/arch/c6x/include/asm/sgmii.h b/arch/c6x/include/asm/sgmii.h
new file mode 100644
index 0000000..b6342b3
--- /dev/null
+++ b/arch/c6x/include/asm/sgmii.h
@@ -0,0 +1,53 @@
+/*
+ * linux/include/asm-c6x/sgmii.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2007, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_SGMII_H
+#define _ASM_C6X_SGMII_H
+
+struct sgmii_config_s {
+ unsigned int loopback;
+ unsigned int master;
+ unsigned int autoneg;
+ unsigned int txconfig;
+ unsigned int rxconfig;
+ unsigned int auxconfig;
+};
+
+extern int sgmii_reset(void);
+extern int sgmii_config(struct sgmii_config_s *);
+
+#ifdef __KERNEL__
+#include <asm/hardware.h>
+
+#define SGMII_SRESET_RESET 0x1
+#define SGMII_SRESET_RTRESET 0x2
+#define SGMII_CTL_AUTONEG 0x01
+#define SGMII_CTL_LOOPBACK 0x10
+#define SGMII_CTL_MASTER 0x20
+
+#define sgmii_setbit_reg(reg, val) \
+ (*((volatile u32 *) (reg)) |= (u32) (val))
+
+#define sgmii_clearbit_reg(reg, val) \
+ (*((volatile u32 *) (reg)) &= ~((u32) (val)))
+
+#define sgmii_set_reg(reg, val) \
+ (*((volatile u32 *) (reg)) = (u32) (val))
+
+#define sgmii_get_reg(reg) \
+ (*((volatile u32 *) (reg)))
+
+#define sgmii_addr_reg(reg) \
+ ((volatile u32 *) (reg))
+
+#endif /* __KERNEL__ */
+#endif /* _ASM_C6X_SGMII_H */
diff --git a/arch/c6x/include/asm/shmbuf.h b/arch/c6x/include/asm/shmbuf.h
new file mode 100644
index 0000000..9e677aa
--- /dev/null
+++ b/arch/c6x/include/asm/shmbuf.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SHMBUF_H
+#define _ASM_C6X_SHMBUF_H
+
+#include <asm-generic/shmbuf.h>
+
+#endif /* _ASM_C6X_SHMBUF_H */
diff --git a/arch/c6x/include/asm/shmparam.h b/arch/c6x/include/asm/shmparam.h
new file mode 100644
index 0000000..0e06c26
--- /dev/null
+++ b/arch/c6x/include/asm/shmparam.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SHMPARAM_H
+#define _ASM_C6X_SHMPARAM_H
+
+#include <asm-generic/shmparam.h>
+
+#endif /* _ASM_C6X_SHMPARAM_H */
diff --git a/arch/c6x/include/asm/sigcontext.h b/arch/c6x/include/asm/sigcontext.h
new file mode 100644
index 0000000..bc171c4
--- /dev/null
+++ b/arch/c6x/include/asm/sigcontext.h
@@ -0,0 +1,83 @@
+/*
+ * linux/include/asm-c6x/sigcontext.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_SIGCONTEXT_H
+#define _ASM_C6X_SIGCONTEXT_H
+
+
+struct sigcontext {
+ unsigned long sc_mask; /* old sigmask */
+ unsigned long sc_sp; /* old user stack pointer */
+
+ unsigned long sc_a4;
+ unsigned long sc_b4;
+ unsigned long sc_a6;
+ unsigned long sc_b6;
+ unsigned long sc_a8;
+ unsigned long sc_b8;
+
+ unsigned long sc_a0;
+ unsigned long sc_a1;
+ unsigned long sc_a2;
+ unsigned long sc_a3;
+ unsigned long sc_a5;
+ unsigned long sc_a7;
+ unsigned long sc_a9;
+
+ unsigned long sc_b0;
+ unsigned long sc_b1;
+ unsigned long sc_b2;
+ unsigned long sc_b3;
+ unsigned long sc_b5;
+ unsigned long sc_b7;
+ unsigned long sc_b9;
+
+ unsigned long sc_a16;
+ unsigned long sc_a17;
+ unsigned long sc_a18;
+ unsigned long sc_a19;
+ unsigned long sc_a20;
+ unsigned long sc_a21;
+ unsigned long sc_a22;
+ unsigned long sc_a23;
+ unsigned long sc_a24;
+ unsigned long sc_a25;
+ unsigned long sc_a26;
+ unsigned long sc_a27;
+ unsigned long sc_a28;
+ unsigned long sc_a29;
+ unsigned long sc_a30;
+ unsigned long sc_a31;
+
+ unsigned long sc_b16;
+ unsigned long sc_b17;
+ unsigned long sc_b18;
+ unsigned long sc_b19;
+ unsigned long sc_b20;
+ unsigned long sc_b21;
+ unsigned long sc_b22;
+ unsigned long sc_b23;
+ unsigned long sc_b24;
+ unsigned long sc_b25;
+ unsigned long sc_b26;
+ unsigned long sc_b27;
+ unsigned long sc_b28;
+ unsigned long sc_b29;
+ unsigned long sc_b30;
+ unsigned long sc_b31;
+
+ unsigned long sc_csr;
+ unsigned long sc_pc;
+};
+
+#endif /* _ASM_C6X_SIGCONTEXT_H */
+
diff --git a/arch/c6x/include/asm/siginfo.h b/arch/c6x/include/asm/siginfo.h
new file mode 100644
index 0000000..01ce660
--- /dev/null
+++ b/arch/c6x/include/asm/siginfo.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SIGINFO_H
+#define _ASM_C6X_SIGINFO_H
+
+#include <asm-generic/siginfo.h>
+
+#endif /* _ASM_C6X_SIGINFO_H */
diff --git a/arch/c6x/include/asm/signal.h b/arch/c6x/include/asm/signal.h
new file mode 100644
index 0000000..f1cd870
--- /dev/null
+++ b/arch/c6x/include/asm/signal.h
@@ -0,0 +1,17 @@
+#ifndef _ASM_C6X_SIGNAL_H
+#define _ASM_C6X_SIGNAL_H
+
+#include <asm-generic/signal.h>
+
+#ifndef __ASSEMBLY__
+#include <linux/linkage.h>
+
+struct pt_regs;
+
+extern asmlinkage int do_rt_sigreturn(struct pt_regs *regs);
+extern asmlinkage void do_notify_resume(struct pt_regs *regs,
+ u32 thread_info_flags,
+ int syscall);
+#endif
+
+#endif /* _ASM_C6X_SIGNAL_H */
diff --git a/arch/c6x/include/asm/socket.h b/arch/c6x/include/asm/socket.h
new file mode 100644
index 0000000..dc28af3
--- /dev/null
+++ b/arch/c6x/include/asm/socket.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SOCKET_H
+#define _ASM_C6X_SOCKET_H
+
+#include <asm-generic/socket.h>
+
+#endif /* _ASM_C6X_SOCKET_H */
diff --git a/arch/c6x/include/asm/sockios.h b/arch/c6x/include/asm/sockios.h
new file mode 100644
index 0000000..fd7ebd9
--- /dev/null
+++ b/arch/c6x/include/asm/sockios.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SOCKIOS_H
+#define _ASM_C6X_SOCKIOS_H
+
+#include <asm-generic/sockios.h>
+
+#endif /* _ASM_C6X_SOCKIOS_H */
diff --git a/arch/c6x/include/asm/stat.h b/arch/c6x/include/asm/stat.h
new file mode 100644
index 0000000..8aafa67
--- /dev/null
+++ b/arch/c6x/include/asm/stat.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_STAT_H
+#define _ASM_C6X_STAT_H
+
+#include <asm-generic/stat.h>
+
+#endif /* _ASM_C6X_STAT_H */
diff --git a/arch/c6x/include/asm/statfs.h b/arch/c6x/include/asm/statfs.h
new file mode 100644
index 0000000..b111ba0
--- /dev/null
+++ b/arch/c6x/include/asm/statfs.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_STATFS_H
+#define _ASM_C6X_STATFS_H
+
+#include <asm-generic/statfs.h>
+
+#endif /* _ASM_C6X_STATFS_H */
diff --git a/arch/c6x/include/asm/string.h b/arch/c6x/include/asm/string.h
new file mode 100644
index 0000000..bfdabde
--- /dev/null
+++ b/arch/c6x/include/asm/string.h
@@ -0,0 +1,29 @@
+/*
+ * linux/include/asm-c6x/string.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_STRING_H
+#define _ASM_C6X_STRING_H
+
+#include <asm/page.h>
+#include <linux/linkage.h>
+
+asmlinkage extern void *memcpy(void *to, const void *from, size_t n);
+extern void *memset(void *s, int c, size_t count);
+extern int memcmp(const void *cs, const void *ct, size_t count);
+extern void *memmove(void *s1, const void *s2, size_t n);
+
+#define __HAVE_ARCH_MEMCPY
+#define __HAVE_ARCH_MEMMOVE
+#define __HAVE_ARCH_MEMSET
+#define __HAVE_ARCH_MEMCMP
+
+#endif /* _ASM_C6X_STRING_H */
diff --git a/arch/c6x/include/asm/swab.h b/arch/c6x/include/asm/swab.h
new file mode 100644
index 0000000..909986f
--- /dev/null
+++ b/arch/c6x/include/asm/swab.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_SWAB_H
+#define _ASM_C6X_SWAB_H
+
+#include <asm-generic/swab.h>
+
+#endif /* _ASM_C6X_SWAB_H */
diff --git a/arch/c6x/include/asm/syscalls.h b/arch/c6x/include/asm/syscalls.h
new file mode 100644
index 0000000..f1a1130
--- /dev/null
+++ b/arch/c6x/include/asm/syscalls.h
@@ -0,0 +1,58 @@
+/*
+ * syscalls.h - Linux syscall interfaces (C6X-specific)
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+
+#ifndef __ASM_C6X_SYSCALLS_H
+#define __ASM_C6X_SYSCALLS_H
+
+#include <linux/compiler.h>
+#include <linux/linkage.h>
+#include <linux/types.h>
+
+/* The array of function pointers for syscalls. */
+extern void *sys_call_table[];
+
+/* The following are trampolines in entry.S to handle 64-bit arguments */
+extern long sys_pread_c6x(unsigned int fd, char __user *buf,
+ size_t count, off_t pos_low, off_t pos_high);
+extern long sys_pwrite_c6x(unsigned int fd, const char __user *buf,
+ size_t count, off_t pos_low, off_t pos_high);
+extern long sys_truncate64_c6x(const char __user *path,
+ off_t length_low, off_t length_high);
+extern long sys_ftruncate64_c6x(unsigned int fd,
+ off_t length_low, off_t length_high);
+extern long sys_fadvise64_c6x(int fd, u32 offset_lo, u32 offset_hi,
+ u32 len, int advice);
+extern long sys_fadvise64_64_c6x(int fd, u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi, int advice);
+extern long sys_fallocate_c6x(int fd, int mode,
+ u32 offset_lo, u32 offset_hi,
+ u32 len_lo, u32 len_hi);
+extern int sys_cache_sync(unsigned long s, unsigned long e);
+
+struct pt_regs;
+
+extern asmlinkage int c6x_vfork(struct pt_regs *regs);
+extern asmlinkage int c6x_clone(struct pt_regs *regs);
+extern asmlinkage long c6x_execve(const char __user *name,
+ const char __user *const __user *argv,
+ const char __user *const __user *envp,
+ struct pt_regs *regs);
+
+
+#include <asm-generic/syscalls.h>
+
+#endif /* __ASM_C6X_SYSCALLS_H */
diff --git a/arch/c6x/include/asm/system.h b/arch/c6x/include/asm/system.h
new file mode 100644
index 0000000..fe9ff5a
--- /dev/null
+++ b/arch/c6x/include/asm/system.h
@@ -0,0 +1,194 @@
+/*
+ * linux/include/asm-c6x/system.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_SYSTEM_H
+#define _ASM_C6X_SYSTEM_H
+
+#include <linux/linkage.h>
+#include <linux/irqflags.h>
+
+#define prepare_to_switch() do { } while (0)
+
+struct task_struct;
+struct thread_struct;
+asmlinkage void *__switch_to(struct thread_struct *prev,
+ struct thread_struct *next,
+ struct task_struct *tsk);
+
+#define switch_to(prev, next, last) \
+ do { \
+ current->thread.wchan = (u_long) __builtin_return_address(0); \
+ (last) = __switch_to(&(prev)->thread, \
+ &(next)->thread, (prev)); \
+ mb(); \
+ current->thread.wchan = 0; \
+ } while (0)
+
+/* Reset the board */
+#define HARD_RESET_NOW()
+
+#define get_creg(reg) \
+ ({ unsigned int __x; asm volatile ("mvc .s2 " #reg ",%0\n" : "=b"(__x)); __x; })
+
+#define set_creg(reg, v) \
+ do { unsigned int __x = (unsigned int)(v); \
+ asm volatile ("mvc .s2 %0," #reg "\n" : : "b"(__x)); \
+ } while (0)
+
+#define or_creg(reg, n) \
+ do { unsigned __x, __n = (unsigned)(n); \
+ asm volatile ("mvc .s2 " #reg ",%0\n" \
+ "or .l2 %1,%0,%0\n" \
+ "mvc .s2 %0," #reg "\n" \
+ "nop\n" \
+ : "=&b"(__x) : "b"(__n)); \
+ } while (0)
+
+#define and_creg(reg, n) \
+ do { unsigned __x, __n = (unsigned)(n); \
+ asm volatile ("mvc .s2 " #reg ",%0\n" \
+ "and .l2 %1,%0,%0\n" \
+ "mvc .s2 %0," #reg "\n" \
+ "nop\n" \
+ : "=&b"(__x) : "b"(__n)); \
+ } while (0)
+
+#define get_coreid() (get_creg(DNUM) & 0xff)
+
+/*
+ * Interrupt management
+ */
+
+/* Return from interrupt function */
+#define iret() asm volatile("B .S2 IRP\n" \
+ "NOP 5\n")
+
+/* Set/get IST */
+#define set_ist(x) set_creg(ISTP, x)
+#define get_ist() get_creg(ISTP)
+
+#ifdef __TMS320C6XPLUS__
+#define __dint() asm volatile ("DINT\n")
+#define __rint() asm volatile ("RINT\n")
+#endif
+
+/*
+ * Exception management
+ */
+
+#ifdef __TMS320C6XPLUS__
+asmlinkage void enable_exception(void);
+#define disable_exception()
+#define get_except_type() get_creg(EFR)
+#define ack_exception(type) set_creg(ECR, 1 << (type))
+#define get_iexcept() get_creg(IERR)
+#define set_iexcept(mask) set_creg(IERR, (mask))
+#else
+#define enable_exception()
+#define disable_exception()
+#define get_except_type()
+#define ack_exception(type)
+#define get_iexcept()
+#define set_iexcept(mask)
+#endif
+
+/*
+ * Misc. functions
+ */
+
+/* Return from exception function */
+#define eret() { asm("B .S2 NRP\n"); \
+ asm("NOP 5\n"); }
+
+#define nop() asm("NOP\n");
+#define mb() barrier()
+#define rmb() barrier()
+#define wmb() barrier()
+#define set_mb(var, value) do { var = value; mb(); } while (0)
+#define set_wmb(var, value) do { var = value; wmb(); } while (0)
+
+#define smp_mb() barrier()
+#define smp_rmb() barrier()
+#define smp_wmb() barrier()
+#define smp_read_barrier_depends() do { } while (0)
+
+#define xchg(ptr, x) \
+ ((__typeof__(*(ptr)))__xchg((unsigned int)(x), (void *) (ptr), \
+ sizeof(*(ptr))))
+#define tas(ptr) xchg((ptr), 1)
+
+unsigned int _lmbd(unsigned int, unsigned int);
+unsigned int _bitr(unsigned int);
+
+struct __xchg_dummy { unsigned int a[100]; };
+#define __xg(x) ((volatile struct __xchg_dummy *)(x))
+
+static inline unsigned int __xchg(unsigned int x, volatile void *ptr, int size)
+{
+ unsigned int tmp;
+ unsigned long flags;
+
+ local_irq_save(flags);
+
+ switch (size) {
+ case 1:
+ tmp = 0;
+ tmp = *((unsigned char *) ptr);
+ *((unsigned char *) ptr) = (unsigned char) x;
+ break;
+ case 2:
+ tmp = 0;
+ tmp = *((unsigned short *) ptr);
+ *((unsigned short *) ptr) = x;
+ break;
+ case 4:
+ tmp = 0;
+ tmp = *((unsigned int *) ptr);
+ *((unsigned int *) ptr) = x;
+ break;
+ }
+ local_irq_restore(flags);
+ return tmp;
+}
+
+#include <asm-generic/cmpxchg-local.h>
+
+/*
+ * cmpxchg_local and cmpxchg64_local are atomic wrt current CPU. Always make
+ * them available.
+ */
+#define cmpxchg_local(ptr, o, n) \
+ ((__typeof__(*(ptr)))__cmpxchg_local_generic((ptr), \
+ (unsigned long)(o), \
+ (unsigned long)(n), \
+ sizeof(*(ptr))))
+#define cmpxchg64_local(ptr, o, n) __cmpxchg64_local_generic((ptr), (o), (n))
+
+#include <asm-generic/cmpxchg.h>
+
+#define _extu(x, s, e) \
+ ({ unsigned int __x; \
+ asm volatile ("extu .S2 %3,%1,%2,%0\n" : \
+ "=b"(__x) : "n"(s), "n"(e), "b"(x)); \
+ __x; })
+
+
+extern unsigned int c6x_core_freq;
+
+struct pt_regs;
+
+extern void die(char *str, struct pt_regs *fp, int nr);
+extern asmlinkage int process_exception(struct pt_regs *regs);
+extern void time_init(void);
+extern void free_initmem(void);
+
+#endif /* _ASM_C6X_SYSTEM_H */
diff --git a/arch/c6x/include/asm/termbits.h b/arch/c6x/include/asm/termbits.h
new file mode 100644
index 0000000..146dfad
--- /dev/null
+++ b/arch/c6x/include/asm/termbits.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_TERMBITS_H
+#define _ASM_C6X_TERMBITS_H
+
+#include <asm-generic/termbits.h>
+
+#endif /* _ASM_C6X_TERMBITS_H */
diff --git a/arch/c6x/include/asm/termios.h b/arch/c6x/include/asm/termios.h
new file mode 100644
index 0000000..77fd1da
--- /dev/null
+++ b/arch/c6x/include/asm/termios.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_TERMIOS_H
+#define _ASM_C6X_TERMIOS_H
+
+#include <asm-generic/termios.h>
+
+#endif /* _ASM_C6X_TERMIOS_H */
diff --git a/arch/c6x/include/asm/thread_info.h b/arch/c6x/include/asm/thread_info.h
new file mode 100644
index 0000000..c1a3dd8
--- /dev/null
+++ b/arch/c6x/include/asm/thread_info.h
@@ -0,0 +1,123 @@
+/*
+ * linux/include/asm-c6x/thread_info.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Updated for 2.6.3x: Mark Salter <[email protected]>
+ *
+ * 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_C6X_THREAD_INFO_H
+#define _ASM_C6X_THREAD_INFO_H
+
+#ifdef __KERNEL__
+
+#include <asm/page.h>
+
+#ifdef CONFIG_4KSTACKS
+#define THREAD_SIZE 4096
+#define THREAD_SHIFT 12
+#define THREAD_ORDER 0
+#else
+#define THREAD_SIZE 8192
+#define THREAD_SHIFT 13
+#define THREAD_ORDER 1
+#endif
+
+#define THREAD_START_SP (THREAD_SIZE - 8)
+
+#ifndef __ASSEMBLY__
+
+typedef struct {
+ unsigned long seg;
+} mm_segment_t;
+
+/*
+ * low level task data.
+ */
+struct thread_info {
+ struct task_struct *task; /* main task structure */
+ struct exec_domain *exec_domain; /* execution domain */
+ unsigned long flags; /* low level flags */
+ int cpu; /* cpu we're on */
+ int preempt_count; /* 0 => preemptable, <0 => BUG */
+ mm_segment_t addr_limit; /* thread address space */
+ struct restart_block restart_block;
+};
+
+/*
+ * macros/functions for gaining access to the thread information structure
+ *
+ * preempt_count needs to be 1 initially, until the scheduler is functional.
+ */
+#define INIT_THREAD_INFO(tsk) \
+{ \
+ .task = &tsk, \
+ .exec_domain = &default_exec_domain, \
+ .flags = 0, \
+ .cpu = 0, \
+ .preempt_count = INIT_PREEMPT_COUNT, \
+ .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)
+
+/* get the thread information struct of current task */
+static inline __attribute__((const))
+struct thread_info *current_thread_info(void)
+{
+ struct thread_info *ti;
+ asm volatile (" clr .s2 B15,0,%1,%0\n"
+ : "=b" (ti)
+ : "Iu5" (THREAD_SHIFT - 1));
+ return ti;
+}
+
+#define __HAVE_ARCH_THREAD_INFO_ALLOCATOR
+
+/* thread information allocation */
+#ifdef CONFIG_DEBUG_STACK_USAGE
+#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK | __GFP_ZERO)
+#else
+#define THREAD_FLAGS (GFP_KERNEL | __GFP_NOTRACK)
+#endif
+
+#define alloc_thread_info_node(tsk, node) \
+ ((struct thread_info *)__get_free_pages(THREAD_FLAGS, THREAD_ORDER))
+
+#define free_thread_info(ti) free_pages((unsigned long) (ti), THREAD_ORDER)
+#define get_thread_info(ti) get_task_struct((ti)->task)
+#define put_thread_info(ti) put_task_struct((ti)->task)
+#endif /* __ASSEMBLY__ */
+
+#define PREEMPT_ACTIVE 0x10000000
+
+/*
+ * thread information flag bit numbers
+ * - pending work-to-be-done flags are in LSW
+ * - other flags in MSW
+ */
+#define TIF_SYSCALL_TRACE 0 /* syscall trace active */
+#define TIF_NOTIFY_RESUME 1 /* resumption notification requested */
+#define TIF_SIGPENDING 2 /* signal pending */
+#define TIF_NEED_RESCHED 3 /* rescheduling necessary */
+#define TIF_RESTORE_SIGMASK 4 /* restore signal mask in do_signal() */
+
+#define TIF_POLLING_NRFLAG 16 /* true if poll_idle() is polling TIF_NEED_RESCHED */
+#define TIF_MEMDIE 17 /* OOM killer killed process */
+
+#define TIF_WORK_MASK 0x00007FFE /* work to do on interrupt/exception return */
+#define TIF_ALLWORK_MASK 0x00007FFF /* work to do on any return to u-space */
+
+#endif /* __KERNEL__ */
+
+#endif /* _ASM_C6X_THREAD_INFO_H */
diff --git a/arch/c6x/include/asm/timer.h b/arch/c6x/include/asm/timer.h
new file mode 100644
index 0000000..8127a63
--- /dev/null
+++ b/arch/c6x/include/asm/timer.h
@@ -0,0 +1,31 @@
+/*
+ * linux/include/asm-c6x/timer.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2005, 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_TIMER_H
+#define _ASM_C6X_TIMER_H
+
+#include <linux/interrupt.h>
+#include <mach/timer.h>
+
+#ifdef CONFIG_USE_RT_TIMER
+extern void adjust_time(void);
+#endif
+
+#define TIMER_REG(reg) (*((volatile unsigned int *) (reg)))
+#define TIMER_REG64(reg) (*((volatile unsigned long long *) (reg)))
+
+#ifndef __ASSEMBLY__
+extern int c6x_arch_init_clocksource(void);
+extern int c6x_arch_init_clockevents(void);
+#endif /* __ASSEMBLY__ */
+
+#endif /*_ASM_C6X_TIMER_H */
diff --git a/arch/c6x/include/asm/timex.h b/arch/c6x/include/asm/timex.h
new file mode 100644
index 0000000..9570f58
--- /dev/null
+++ b/arch/c6x/include/asm/timex.h
@@ -0,0 +1,43 @@
+/*
+ * linux/include/asm-c6x/timex.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Modified for 2.6.34: Mark Salter <[email protected]>
+ *
+ * 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_C6X_TIMEX_H
+#define _ASM_C6X_TIMEX_H
+
+/*
+ * This should be close enough...
+ */
+#define CLOCK_TICK_RATE ((1000 * 1000000UL) / 6)
+
+/* 64-bit timestamp */
+typedef unsigned long long cycles_t;
+
+extern cycles_t cacheflush_time;
+
+static inline cycles_t get_cycles(void)
+{
+ unsigned l, h;
+
+ asm volatile (" dint\n"
+ " mvc .s2 TSCL,%0\n"
+ " mvc .s2 TSCH,%1\n"
+ " rint\n"
+ : "=b"(l), "=b"(h));
+ return ((cycles_t)h << 32) | l;
+}
+
+extern int init_tsc_clocksource(void);
+extern int init_timer64_clocksource(void);
+
+#endif /* _ASM_C6X_TIMEX_H */
diff --git a/arch/c6x/include/asm/tlb.h b/arch/c6x/include/asm/tlb.h
new file mode 100644
index 0000000..8709e5e
--- /dev/null
+++ b/arch/c6x/include/asm/tlb.h
@@ -0,0 +1,8 @@
+#ifndef _ASM_C6X_TLB_H
+#define _ASM_C6X_TLB_H
+
+#define tlb_flush(tlb) flush_tlb_mm((tlb)->mm)
+
+#include <asm-generic/tlb.h>
+
+#endif /* _ASM_C6X_TLB_H */
diff --git a/arch/c6x/include/asm/tlbflush.h b/arch/c6x/include/asm/tlbflush.h
new file mode 100644
index 0000000..e00f0b9
--- /dev/null
+++ b/arch/c6x/include/asm/tlbflush.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_TLBFLUSH_H
+#define _ASM_C6X_TLBFLUSH_H
+
+#include <asm-generic/tlbflush.h>
+
+#endif /* _ASM_C6X_TLBFLUSH_H */
diff --git a/arch/c6x/include/asm/topology.h b/arch/c6x/include/asm/topology.h
new file mode 100644
index 0000000..30767fd
--- /dev/null
+++ b/arch/c6x/include/asm/topology.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_TOPOLOGY_H
+#define _ASM_C6X_TOPOLOGY_H
+
+#include <asm-generic/topology.h>
+
+#endif /* _ASM_C6X_TOPOLOGY_H */
diff --git a/arch/c6x/include/asm/traps.h b/arch/c6x/include/asm/traps.h
new file mode 100644
index 0000000..d2ab603
--- /dev/null
+++ b/arch/c6x/include/asm/traps.h
@@ -0,0 +1,39 @@
+/*
+ * linux/include/asm-c6x/traps.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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_C6X_TRAPS_H
+#define _ASM_C6X_TRAPS_H
+
+#ifdef CONFIG_TMS320C64XPLUS
+
+#define EXCEPT_TYPE_NXF 31 /* NMI */
+#define EXCEPT_TYPE_EXC 30 /* external exception */
+#define EXCEPT_TYPE_IXF 1 /* internal exception */
+#define EXCEPT_TYPE_SXF 0 /* software exception */
+
+#define EXCEPT_CAUSE_LBX (1 << 7) /* loop buffer exception */
+#define EXCEPT_CAUSE_PRX (1 << 6) /* privilege exception */
+#define EXCEPT_CAUSE_RAX (1 << 5) /* resource access exception */
+#define EXCEPT_CAUSE_RCX (1 << 4) /* resource conflict exception */
+#define EXCEPT_CAUSE_OPX (1 << 3) /* opcode exception */
+#define EXCEPT_CAUSE_EPX (1 << 2) /* execute packet exception */
+#define EXCEPT_CAUSE_FPX (1 << 1) /* fetch packet exception */
+#define EXCEPT_CAUSE_IFX (1 << 0) /* instruction fetch exception */
+
+struct exception_info {
+ char *kernel_str;
+ int signo;
+ int code;
+};
+
+#endif /* CONFIG_TMS320C64XPLUS */
+#endif /* _ASM_C6X_TRAPS_H */
diff --git a/arch/c6x/include/asm/types.h b/arch/c6x/include/asm/types.h
new file mode 100644
index 0000000..c2fe78b
--- /dev/null
+++ b/arch/c6x/include/asm/types.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_TYPES_H
+#define _ASM_C6X_TYPES_H
+
+#include <asm-generic/types.h>
+
+#endif /* _ASM_C6X_TYPES_H */
diff --git a/arch/c6x/include/asm/uaccess.h b/arch/c6x/include/asm/uaccess.h
new file mode 100644
index 0000000..acb0405
--- /dev/null
+++ b/arch/c6x/include/asm/uaccess.h
@@ -0,0 +1,103 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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_C6X_UACCESS_H
+#define _ASM_C6X_UACCESS_H
+
+#include <linux/types.h>
+#include <linux/compiler.h>
+#include <linux/string.h>
+
+/*
+ * __copy_from_user/copy_to_user are based on ones in asm-generic/uaccess.h
+ *
+ * C6X supports unaligned 32 and 64 bit loads and stores.
+ */
+static inline __must_check long __copy_from_user(void *to,
+ const void __user *from, unsigned long n)
+{
+ u32 tmp32;
+ u64 tmp64;
+
+ if (__builtin_constant_p(n)) {
+ switch (n) {
+ case 1:
+ *(u8 *)to = *(u8 __force *)from;
+ return 0;
+ case 4:
+ asm volatile ("ldnw .d1t1 *%2,%0\n"
+ "nop 4\n"
+ "stnw .d1t1 %0,*%1\n"
+ : "=&a"(tmp32)
+ : "A"(to), "a"(from)
+ : "memory");
+ return 0;
+ case 8:
+ asm volatile ("ldndw .d1t1 *%2,%0\n"
+ "nop 4\n"
+ "stndw .d1t1 %0,*%1\n"
+ : "=&a"(tmp64)
+ : "a"(to), "a"(from)
+ : "memory");
+ return 0;
+ default:
+ break;
+ }
+ }
+
+ memcpy(to, (const void __force *)from, n);
+ return 0;
+}
+
+static inline __must_check long __copy_to_user(void __user *to,
+ const void *from, unsigned long n)
+{
+ u32 tmp32;
+ u64 tmp64;
+
+ if (__builtin_constant_p(n)) {
+ switch (n) {
+ case 1:
+ *(u8 __force *)to = *(u8 *)from;
+ return 0;
+ case 4:
+ asm volatile ("ldnw .d1t1 *%2,%0\n"
+ "nop 4\n"
+ "stnw .d1t1 %0,*%1\n"
+ : "=&a"(tmp32)
+ : "a"(to), "a"(from)
+ : "memory");
+ return 0;
+ case 8:
+ asm volatile ("ldndw .d1t1 *%2,%0\n"
+ "nop 4\n"
+ "stndw .d1t1 %0,*%1\n"
+ : "=&a"(tmp64)
+ : "a"(to), "a"(from)
+ : "memory");
+ return 0;
+ default:
+ break;
+ }
+ }
+
+ memcpy((void __force *)to, from, n);
+ return 0;
+}
+
+#define __copy_to_user __copy_to_user
+#define __copy_from_user __copy_from_user
+
+extern int _access_ok(unsigned long addr, unsigned long size);
+#ifdef CONFIG_ACCESS_CHECK
+#define __access_ok _access_ok
+#endif
+
+#include <asm-generic/uaccess.h>
+
+#endif /* _ASM_C6X_UACCESS_H */
diff --git a/arch/c6x/include/asm/ucontext.h b/arch/c6x/include/asm/ucontext.h
new file mode 100644
index 0000000..026bc0a
--- /dev/null
+++ b/arch/c6x/include/asm/ucontext.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_UCONTEXT_H
+#define _ASM_C6X_UCONTEXT_H
+
+#include <asm-generic/ucontext.h>
+
+#endif /* _ASM_C6X_UCONTEXT_H */
diff --git a/arch/c6x/include/asm/unaligned.h b/arch/c6x/include/asm/unaligned.h
new file mode 100644
index 0000000..a9fa06c
--- /dev/null
+++ b/arch/c6x/include/asm/unaligned.h
@@ -0,0 +1,290 @@
+/*
+ * arch/c6x/include/asm/unaligned.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ * Rewritten for 2.6.3x: Mark Salter <[email protected]>
+ *
+ * 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_C6X_UNALIGNED_H
+#define _ASM_C6X_UNALIGNED_H
+
+/*
+ * The C64x+ can do unaligned word and dword accesses in hardware
+ * using special load/store instructions.
+ */
+
+static inline u16 __get_unaligned_le16(const u8 *p)
+{
+ return p[0] | p[1] << 8;
+}
+
+static inline u16 __get_unaligned_be16(const u8 *p)
+{
+ return p[0] << 8 | p[1];
+}
+
+static inline void __put_unaligned_le16(u16 val, u8 *p)
+{
+ *p++ = val;
+ *p++ = val >> 8;
+}
+
+static inline void __put_unaligned_be16(u16 val, u8 *p)
+{
+ *p++ = val >> 8;
+ *p++ = val;
+}
+
+static inline u32 __get_unaligned32_swab(const u8 *p)
+{
+ u32 val = (u32) p;
+ asm volatile (" ldnw .d1t1 *%0,%0\n"
+ " nop 4\n"
+ " swap2 .s1 %0,%0\n"
+ " swap4 .l1 %0,%0\n"
+ : "+a"(val));
+ return val;
+}
+
+static inline u32 __get_unaligned32(const u8 *p)
+{
+ u32 val = (u32) p;
+ asm volatile (" ldnw .d1t1 *%0,%0\n"
+ " nop 4\n"
+ : "+a"(val));
+ return val;
+}
+
+static inline void __put_unaligned32_swab(u32 val, u8 *p)
+{
+ asm volatile (" swap2 .s1 %0,%0\n"
+ " swap4 .l1 %0,%0\n"
+ " stnw .d2t1 %0,*%1\n"
+ : : "a"(val), "b"(p) : "memory");
+}
+
+static inline void __put_unaligned32(u32 val, u8 *p)
+{
+ asm volatile (" stnw .d2t1 %0,*%1\n"
+ : : "a"(val), "b"(p) : "memory");
+}
+
+static inline u64 __get_unaligned64_swab(const u8 *p)
+{
+ u64 val;
+
+ asm volatile (" ldndw .d2t1 *%1,%0\n"
+ " nop 4\n"
+ " swap2 .s1 %p0,%P0\n"
+ " || swap2 .l1 %P0,%p0\n"
+ " swap4 .l1 %p0,%p0\n"
+ " swap4 .l1 %P0,%P0\n"
+ : "=a"(val) : "b"(p));
+ return val;
+}
+
+static inline u64 __get_unaligned64(const u8 *p)
+{
+ u64 val;
+ asm volatile (" ldndw .d1t1 *%1,%0\n"
+ " nop 4\n"
+ : "=a"(val) : "a"(p));
+ return val;
+}
+
+static inline void __put_unaligned64_swab(u64 val, u8 *p)
+{
+ asm volatile (" swap2 .s1 %p0,%P0\n"
+ " || swap2 .l1 %P0,%p0\n"
+ " swap4 .l1 %p0,%p0\n"
+ " swap4 .l1 %P0,%P0\n"
+ " stndw .d2t1 %0,*%1\n"
+ : : "a"(val), "b"(p) : "memory");
+}
+
+static inline void __put_unaligned64(u64 val, u8 *p)
+{
+ asm volatile (" stndw .d2t1 %0,*%1\n"
+ : : "a"(val), "b"(p) : "memory");
+}
+
+
+static inline u16 get_unaligned_le16(const void *p)
+{
+ return __get_unaligned_le16((const u8 *)p);
+}
+
+static inline u16 get_unaligned_be16(const void *p)
+{
+ return __get_unaligned_be16((const u8 *)p);
+}
+
+static inline void put_unaligned_le16(u16 val, void *p)
+{
+ __put_unaligned_le16(val, p);
+}
+
+static inline void put_unaligned_be16(u16 val, void *p)
+{
+ __put_unaligned_be16(val, p);
+}
+
+
+static inline u32 get_unaligned_le32(const void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ return __get_unaligned32_swab((const u8 *)p);
+#else
+ return __get_unaligned32((const u8 *)p);
+#endif
+}
+
+static inline u32 get_unaligned_be32(const void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ return __get_unaligned32((const u8 *)p);
+#else
+ return __get_unaligned32_swab((const u8 *)p);
+#endif
+}
+
+static inline void put_unaligned_le32(u32 val, void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ __put_unaligned32_swab(val, p);
+#else
+ __put_unaligned32(val, p);
+#endif
+}
+
+static inline void put_unaligned_be32(u32 val, void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ __put_unaligned32(val, p);
+#else
+ __put_unaligned32_swab(val, p);
+#endif
+}
+
+static inline u64 get_unaligned_le64(const void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ return __get_unaligned64_swab((const u8 *)p);
+#else
+ return __get_unaligned64((const u8 *)p);
+#endif
+}
+
+static inline u64 get_unaligned_be64(const void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ return __get_unaligned64((const u8 *)p);
+#else
+ return __get_unaligned64_swab((const u8 *)p);
+#endif
+}
+
+static inline void put_unaligned_le64(u64 val, void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ __put_unaligned64_swab(val, p);
+#else
+ __put_unaligned64(val, p);
+#endif
+}
+
+static inline void put_unaligned_be64(u64 val, void *p)
+{
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ __put_unaligned64(val, p);
+#else
+ __put_unaligned64_swab(val, p);
+#endif
+}
+
+/*
+ * Cause a link-time error if we try an unaligned access other than
+ * 1,2,4 or 8 bytes long
+ */
+extern int __bad_unaligned_access_size(void);
+
+#define __get_unaligned_le(ptr) (typeof(*(ptr)))({ \
+ sizeof(*(ptr)) == 1 ? *(ptr) : \
+ (sizeof(*(ptr)) == 2 ? get_unaligned_le16((ptr)) : \
+ (sizeof(*(ptr)) == 4 ? get_unaligned_le32((ptr)) : \
+ (sizeof(*(ptr)) == 8 ? get_unaligned_le64((ptr)) : \
+ __bad_unaligned_access_size()))); \
+ })
+
+#define __get_unaligned_be(ptr) (__force typeof(*(ptr)))({ \
+ sizeof(*(ptr)) == 1 ? *(ptr) : \
+ (sizeof(*(ptr)) == 2 ? get_unaligned_be16((ptr)) : \
+ (sizeof(*(ptr)) == 4 ? get_unaligned_be32((ptr)) : \
+ (sizeof(*(ptr)) == 8 ? get_unaligned_be64((ptr)) : \
+ __bad_unaligned_access_size()))); \
+ })
+
+#define __put_unaligned_le(val, ptr) ({ \
+ void *__gu_p = (ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(u8 *)__gu_p = (__force u8)(val); \
+ break; \
+ case 2: \
+ put_unaligned_le16((__force u16)(val), __gu_p); \
+ break; \
+ case 4: \
+ put_unaligned_le32((__force u32)(val), __gu_p); \
+ break; \
+ case 8: \
+ put_unaligned_le64((__force u64)(val), __gu_p); \
+ break; \
+ default: \
+ __bad_unaligned_access_size(); \
+ break; \
+ } \
+ (void)0; })
+
+#define __put_unaligned_be(val, ptr) ({ \
+ void *__gu_p = (ptr); \
+ switch (sizeof(*(ptr))) { \
+ case 1: \
+ *(u8 *)__gu_p = (__force u8)(val); \
+ break; \
+ case 2: \
+ put_unaligned_be16((__force u16)(val), __gu_p); \
+ break; \
+ case 4: \
+ put_unaligned_be32((__force u32)(val), __gu_p); \
+ break; \
+ case 8: \
+ put_unaligned_be64((__force u64)(val), __gu_p); \
+ break; \
+ default: \
+ __bad_unaligned_access_size(); \
+ break; \
+ } \
+ (void)0; })
+
+
+#ifdef _BIG_ENDIAN
+#define get_unaligned __get_unaligned_be
+#define put_unaligned __put_unaligned_be
+#define get_unaligned16 get_unaligned_be16
+#define get_unaligned32 get_unaligned_be32
+#define get_unaligned64 get_unaligned_be64
+#else
+#define get_unaligned __get_unaligned_le
+#define put_unaligned __put_unaligned_le
+#define get_unaligned16 get_unaligned_le16
+#define get_unaligned32 get_unaligned_le32
+#define get_unaligned64 get_unaligned_le64
+#endif
+
+#endif /* _ASM_C6X_UNALIGNED_H */
diff --git a/arch/c6x/include/asm/unistd.h b/arch/c6x/include/asm/unistd.h
new file mode 100644
index 0000000..9064c6b
--- /dev/null
+++ b/arch/c6x/include/asm/unistd.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ *
+ * Based on arch/tile version.
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation, version 2.
+ *
+ * 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, GOOD TITLE or
+ * NON INFRINGEMENT. See the GNU General Public License for
+ * more details.
+ */
+#if !defined(_ASM_C6X_UNISTD_H) || defined(__SYSCALL)
+#define _ASM_C6X_UNISTD_H
+
+#define __ARCH_WANT_SYSCALL_DEPRECATED
+#define __ARCH_WANT_SYSCALL_NO_AT
+#define __ARCH_WANT_SYSCALL_NO_FLAGS
+#define __ARCH_WANT_SYSCALL_OFF_T
+#define __ARCH_WANT_IPC_PARSE_VERSION
+
+/* Use the standard ABI for syscalls. */
+#include <asm-generic/unistd.h>
+
+/* C6X-specific syscalls. */
+#define __NR_cache_sync (__NR_arch_specific_syscall + 0)
+__SYSCALL(__NR_cache_sync, sys_cache_sync)
+
+#endif /* _ASM_C6X_UNISTD_H */
diff --git a/arch/c6x/include/asm/user.h b/arch/c6x/include/asm/user.h
new file mode 100644
index 0000000..4792a60
--- /dev/null
+++ b/arch/c6x/include/asm/user.h
@@ -0,0 +1 @@
+#include <asm-generic/user.h>
diff --git a/arch/c6x/include/asm/vga.h b/arch/c6x/include/asm/vga.h
new file mode 100644
index 0000000..d924655
--- /dev/null
+++ b/arch/c6x/include/asm/vga.h
@@ -0,0 +1,6 @@
+#ifndef _ASM_C6X_VGA_H
+#define _ASM_C6X_VGA_H
+
+#include <asm-generic/vga.h>
+
+#endif /* _ASM_C6X_VGA_H */
--
1.6.2.5

2011-05-11 21:07:08

by Mark Salter

[permalink] [raw]
Subject: [PATCH 09/16] C6X: add kernel files

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/kernel/Makefile | 13 +
arch/c6x/kernel/asm-offsets.c | 127 ++++++
arch/c6x/kernel/c6x_ksyms.c | 75 ++++
arch/c6x/kernel/clkdev.c | 192 +++++++++
arch/c6x/kernel/early_printk.c | 81 ++++
arch/c6x/kernel/entry.S | 851 ++++++++++++++++++++++++++++++++++++++++
arch/c6x/kernel/head.S | 127 ++++++
arch/c6x/kernel/irq.c | 119 ++++++
arch/c6x/kernel/module.c | 249 ++++++++++++
arch/c6x/kernel/process.c | 349 ++++++++++++++++
arch/c6x/kernel/ptrace.c | 284 +++++++++++++
arch/c6x/kernel/setup.c | 550 ++++++++++++++++++++++++++
arch/c6x/kernel/signal.c | 384 ++++++++++++++++++
arch/c6x/kernel/switch_to.S | 67 ++++
arch/c6x/kernel/sys_c6x.c | 111 ++++++
arch/c6x/kernel/tags.c | 98 +++++
arch/c6x/kernel/tags.h | 82 ++++
arch/c6x/kernel/time.c | 55 +++
arch/c6x/kernel/traps.c | 416 ++++++++++++++++++++
arch/c6x/kernel/vectors.S | 81 ++++
arch/c6x/kernel/vmlinux.lds.S | 205 ++++++++++
21 files changed, 4516 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/kernel/Makefile
create mode 100644 arch/c6x/kernel/asm-offsets.c
create mode 100644 arch/c6x/kernel/c6x_ksyms.c
create mode 100644 arch/c6x/kernel/clkdev.c
create mode 100644 arch/c6x/kernel/early_printk.c
create mode 100644 arch/c6x/kernel/entry.S
create mode 100644 arch/c6x/kernel/head.S
create mode 100644 arch/c6x/kernel/irq.c
create mode 100644 arch/c6x/kernel/module.c
create mode 100644 arch/c6x/kernel/process.c
create mode 100644 arch/c6x/kernel/ptrace.c
create mode 100644 arch/c6x/kernel/setup.c
create mode 100644 arch/c6x/kernel/signal.c
create mode 100644 arch/c6x/kernel/switch_to.S
create mode 100644 arch/c6x/kernel/sys_c6x.c
create mode 100644 arch/c6x/kernel/tags.c
create mode 100644 arch/c6x/kernel/tags.h
create mode 100644 arch/c6x/kernel/time.c
create mode 100644 arch/c6x/kernel/traps.c
create mode 100644 arch/c6x/kernel/vectors.S
create mode 100644 arch/c6x/kernel/vmlinux.lds.S

diff --git a/arch/c6x/kernel/Makefile b/arch/c6x/kernel/Makefile
new file mode 100644
index 0000000..25cdded
--- /dev/null
+++ b/arch/c6x/kernel/Makefile
@@ -0,0 +1,13 @@
+#
+# Makefile for arch/c6x/kernel/
+#
+
+extra-y := head.o vmlinux.lds
+
+obj-y := process.o traps.o irq.o signal.o ptrace.o \
+ setup.o sys_c6x.o time.o \
+ switch_to.o entry.o vectors.o c6x_ksyms.o tags.o
+
+obj-$(CONFIG_MODULES) += module.o
+obj-$(CONFIG_COMMON_CLKDEV) += clkdev.o
+obj-$(CONFIG_EARLY_PRINTK) += early_printk.o
diff --git a/arch/c6x/kernel/asm-offsets.c b/arch/c6x/kernel/asm-offsets.c
new file mode 100644
index 0000000..52fca25
--- /dev/null
+++ b/arch/c6x/kernel/asm-offsets.c
@@ -0,0 +1,127 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ */
+
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/dma-mapping.h>
+#include <linux/thread_info.h>
+#include <asm/procinfo.h>
+#include <linux/kbuild.h>
+#include <linux/unistd.h>
+
+void foo(void)
+{
+ OFFSET(REGS_A16, pt_regs, a16);
+ OFFSET(REGS_A17, pt_regs, a17);
+ OFFSET(REGS_A18, pt_regs, a18);
+ OFFSET(REGS_A19, pt_regs, a19);
+ OFFSET(REGS_A20, pt_regs, a20);
+ OFFSET(REGS_A21, pt_regs, a21);
+ OFFSET(REGS_A22, pt_regs, a22);
+ OFFSET(REGS_A23, pt_regs, a23);
+ OFFSET(REGS_A24, pt_regs, a24);
+ OFFSET(REGS_A25, pt_regs, a25);
+ OFFSET(REGS_A26, pt_regs, a26);
+ OFFSET(REGS_A27, pt_regs, a27);
+ OFFSET(REGS_A28, pt_regs, a28);
+ OFFSET(REGS_A29, pt_regs, a29);
+ OFFSET(REGS_A30, pt_regs, a30);
+ OFFSET(REGS_A31, pt_regs, a31);
+
+ OFFSET(REGS_B16, pt_regs, b16);
+ OFFSET(REGS_B17, pt_regs, b17);
+ OFFSET(REGS_B18, pt_regs, b18);
+ OFFSET(REGS_B19, pt_regs, b19);
+ OFFSET(REGS_B20, pt_regs, b20);
+ OFFSET(REGS_B21, pt_regs, b21);
+ OFFSET(REGS_B22, pt_regs, b22);
+ OFFSET(REGS_B23, pt_regs, b23);
+ OFFSET(REGS_B24, pt_regs, b24);
+ OFFSET(REGS_B25, pt_regs, b25);
+ OFFSET(REGS_B26, pt_regs, b26);
+ OFFSET(REGS_B27, pt_regs, b27);
+ OFFSET(REGS_B28, pt_regs, b28);
+ OFFSET(REGS_B29, pt_regs, b29);
+ OFFSET(REGS_B30, pt_regs, b30);
+ OFFSET(REGS_B31, pt_regs, b31);
+
+ OFFSET(REGS_A0, pt_regs, a0);
+ OFFSET(REGS_A1, pt_regs, a1);
+ OFFSET(REGS_A2, pt_regs, a2);
+ OFFSET(REGS_A3, pt_regs, a3);
+ OFFSET(REGS_A4, pt_regs, a4);
+ OFFSET(REGS_A5, pt_regs, a5);
+ OFFSET(REGS_A6, pt_regs, a6);
+ OFFSET(REGS_A7, pt_regs, a7);
+ OFFSET(REGS_A8, pt_regs, a8);
+ OFFSET(REGS_A9, pt_regs, a9);
+ OFFSET(REGS_A10, pt_regs, a10);
+ OFFSET(REGS_A11, pt_regs, a11);
+ OFFSET(REGS_A12, pt_regs, a12);
+ OFFSET(REGS_A13, pt_regs, a13);
+ OFFSET(REGS_A14, pt_regs, a14);
+ OFFSET(REGS_A15, pt_regs, a15);
+
+ OFFSET(REGS_B0, pt_regs, b0);
+ OFFSET(REGS_B1, pt_regs, b1);
+ OFFSET(REGS_B2, pt_regs, b2);
+ OFFSET(REGS_B3, pt_regs, b3);
+ OFFSET(REGS_B4, pt_regs, b4);
+ OFFSET(REGS_B5, pt_regs, b5);
+ OFFSET(REGS_B6, pt_regs, b6);
+ OFFSET(REGS_B7, pt_regs, b7);
+ OFFSET(REGS_B8, pt_regs, b8);
+ OFFSET(REGS_B9, pt_regs, b9);
+ OFFSET(REGS_B10, pt_regs, b10);
+ OFFSET(REGS_B11, pt_regs, b11);
+ OFFSET(REGS_B12, pt_regs, b12);
+ OFFSET(REGS_B13, pt_regs, b13);
+ OFFSET(REGS_DP, pt_regs, dp);
+ OFFSET(REGS_SP, pt_regs, sp);
+
+ OFFSET(REGS_TSR, pt_regs, tsr);
+ OFFSET(REGS_ORIG_A4, pt_regs, orig_a4);
+
+ DEFINE(REGS__END, sizeof(struct pt_regs));
+ BLANK();
+
+ OFFSET(THREAD_PC, thread_struct, pc);
+ OFFSET(THREAD_B15_14, thread_struct, b15_14);
+ OFFSET(THREAD_A15_14, thread_struct, a15_14);
+ OFFSET(THREAD_B13_12, thread_struct, b13_12);
+ OFFSET(THREAD_A13_12, thread_struct, a13_12);
+ OFFSET(THREAD_B11_10, thread_struct, b11_10);
+ OFFSET(THREAD_A11_10, thread_struct, a11_10);
+ OFFSET(THREAD_RICL_ICL, thread_struct, ricl_icl);
+ BLANK();
+
+ OFFSET(TASK_STATE, task_struct, state);
+ BLANK();
+
+ OFFSET(THREAD_INFO_FLAGS, thread_info, flags);
+ OFFSET(THREAD_INFO_PREEMPT_COUNT, thread_info, preempt_count);
+ BLANK();
+
+ /* These would be unneccessary if we ran asm files
+ * through the preprocessor.
+ */
+ DEFINE(KTHREAD_SIZE, THREAD_SIZE);
+ DEFINE(KTHREAD_SHIFT, THREAD_SHIFT);
+ DEFINE(KTHREAD_START_SP, THREAD_START_SP);
+ DEFINE(ENOSYS_, ENOSYS);
+ DEFINE(NR_SYSCALLS_, __NR_syscalls);
+
+ DEFINE(_TIF_SYSCALL_TRACE, (1<<TIF_SYSCALL_TRACE));
+ DEFINE(_TIF_NOTIFY_RESUME, (1<<TIF_NOTIFY_RESUME));
+ DEFINE(_TIF_SIGPENDING, (1<<TIF_SIGPENDING));
+ DEFINE(_TIF_NEED_RESCHED, (1<<TIF_NEED_RESCHED));
+ DEFINE(_TIF_POLLING_NRFLAG, (1<<TIF_POLLING_NRFLAG));
+
+ DEFINE(_TIF_ALLWORK_MASK, TIF_ALLWORK_MASK);
+ DEFINE(_TIF_WORK_MASK, TIF_WORK_MASK);
+}
+
diff --git a/arch/c6x/kernel/c6x_ksyms.c b/arch/c6x/kernel/c6x_ksyms.c
new file mode 100644
index 0000000..8ee8a93
--- /dev/null
+++ b/arch/c6x/kernel/c6x_ksyms.c
@@ -0,0 +1,75 @@
+/*
+ * linux/arch/c6x/kernel/c6x_ksyms.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ */
+#include <linux/module.h>
+#include <asm/checksum.h>
+#include <linux/io.h>
+
+/*
+ * libgcc functions - used internally by the compiler...
+ */
+extern int __c6xabi_divi(int dividend, int divisor);
+EXPORT_SYMBOL(__c6xabi_divi);
+
+extern unsigned __c6xabi_divu(unsigned dividend, unsigned divisor);
+EXPORT_SYMBOL(__c6xabi_divu);
+
+extern int __c6xabi_remi(int dividend, int divisor);
+EXPORT_SYMBOL(__c6xabi_remi);
+
+extern unsigned __c6xabi_remu(unsigned dividend, unsigned divisor);
+EXPORT_SYMBOL(__c6xabi_remu);
+
+extern int __c6xabi_divremi(int dividend, int divisor);
+EXPORT_SYMBOL(__c6xabi_divremi);
+
+extern unsigned __c6xabi_divremu(unsigned dividend, unsigned divisor);
+EXPORT_SYMBOL(__c6xabi_divremu);
+
+extern unsigned long long __c6xabi_mpyll(unsigned long long src1,
+ unsigned long long src2);
+EXPORT_SYMBOL(__c6xabi_mpyll);
+
+extern unsigned long long __c6xabi_divull(unsigned long long n,
+ unsigned long long d);
+EXPORT_SYMBOL(__c6xabi_divull);
+
+extern long long __c6xabi_negll(long long src);
+EXPORT_SYMBOL(__c6xabi_negll);
+
+extern unsigned long long __c6xabi_llshl(unsigned long long src1, uint src2);
+EXPORT_SYMBOL(__c6xabi_llshl);
+
+extern long long __c6xabi_llshr(long long src1, uint src2);
+EXPORT_SYMBOL(__c6xabi_llshr);
+
+extern unsigned long long __c6xabi_llshru(unsigned long long src1, uint src2);
+EXPORT_SYMBOL(__c6xabi_llshru);
+
+extern void __c6xabi_strasgi(int *dst, const int *src, unsigned cnt);
+EXPORT_SYMBOL(__c6xabi_strasgi);
+
+extern void __c6xabi_push_rts(void);
+EXPORT_SYMBOL(__c6xabi_push_rts);
+
+extern void __c6xabi_pop_rts(void);
+EXPORT_SYMBOL(__c6xabi_pop_rts);
+
+extern void __c6xabi_strasgi_64plus(int *dst, const int *src, unsigned cnt);
+EXPORT_SYMBOL(__c6xabi_strasgi_64plus);
+
+/* lib functions */
+EXPORT_SYMBOL(memcpy);
+EXPORT_SYMBOL(csum_partial);
+EXPORT_SYMBOL(ip_fast_csum);
+
diff --git a/arch/c6x/kernel/clkdev.c b/arch/c6x/kernel/clkdev.c
new file mode 100644
index 0000000..747c316
--- /dev/null
+++ b/arch/c6x/kernel/clkdev.c
@@ -0,0 +1,192 @@
+/*
+ * arch/c6x/kernel/clkdev.c
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * Original code from: arch/arm/common/clkdev.c
+ *
+ * Copyright (C) 2008 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.
+ *
+ * Helper for the clk API to assist looking up a struct clk.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/errno.h>
+#include <linux/err.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/clk.h>
+
+#include <asm/clkdev.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+
+
+int __weak __clk_get(struct clk *clk)
+{
+ return 1;
+}
+
+void __weak __clk_put(struct clk *clk)
+{
+}
+
+/*
+ * Find the correct struct clk for the device and connection ID.
+ * We do slightly fuzzy matching here:
+ * An entry with a NULL ID is assumed to be a wildcard.
+ * If an entry has a device ID, it must match
+ * If an entry has a connection ID, it must match
+ * Then we take the most specific entry - with the following
+ * order of precedence: dev+con > dev only > con only.
+ */
+static struct clk *clk_find(const char *dev_id, const char *con_id)
+{
+ struct clk_lookup *p;
+ struct clk *clk = NULL;
+ int match, best = 0;
+
+ list_for_each_entry(p, &clocks, node) {
+ match = 0;
+ if (p->dev_id) {
+ if (!dev_id || strcmp(p->dev_id, dev_id))
+ continue;
+ match += 2;
+ }
+ if (p->con_id) {
+ if (!con_id || strcmp(p->con_id, con_id))
+ continue;
+ match += 1;
+ }
+ if (match == 0)
+ continue;
+
+ if (match > best) {
+ clk = p->clk;
+ best = match;
+ }
+ }
+ return clk;
+}
+
+struct clk *clk_get_sys(const char *dev_id, const char *con_id)
+{
+ struct clk *clk;
+
+ mutex_lock(&clocks_mutex);
+ clk = clk_find(dev_id, con_id);
+ if (clk && !__clk_get(clk))
+ clk = NULL;
+ mutex_unlock(&clocks_mutex);
+
+ return clk ? clk : ERR_PTR(-ENOENT);
+}
+EXPORT_SYMBOL(clk_get_sys);
+
+struct clk *clk_get(struct device *dev, const char *con_id)
+{
+ const char *dev_id = dev ? dev_name(dev) : NULL;
+
+ return clk_get_sys(dev_id, con_id);
+}
+EXPORT_SYMBOL(clk_get);
+
+void clk_put(struct clk *clk)
+{
+ __clk_put(clk);
+}
+EXPORT_SYMBOL(clk_put);
+
+void clkdev_add(struct clk_lookup *cl)
+{
+ mutex_lock(&clocks_mutex);
+ list_add_tail(&cl->node, &clocks);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clkdev_add);
+
+void __init clkdev_add_table(struct clk_lookup *cl, size_t num)
+{
+ mutex_lock(&clocks_mutex);
+ while (num--) {
+ list_add_tail(&cl->node, &clocks);
+ cl++;
+ }
+ mutex_unlock(&clocks_mutex);
+}
+
+#define MAX_DEV_ID 20
+#define MAX_CON_ID 16
+
+struct clk_lookup_alloc {
+ struct clk_lookup cl;
+ char dev_id[MAX_DEV_ID];
+ char con_id[MAX_CON_ID];
+};
+
+struct clk_lookup *clkdev_alloc(struct clk *clk, const char *con_id,
+ const char *dev_fmt, ...)
+{
+ struct clk_lookup_alloc *cla;
+
+ cla = kzalloc(sizeof(*cla), GFP_KERNEL);
+ if (!cla)
+ return NULL;
+
+ cla->cl.clk = clk;
+ if (con_id) {
+ strlcpy(cla->con_id, con_id, sizeof(cla->con_id));
+ cla->cl.con_id = cla->con_id;
+ }
+
+ if (dev_fmt) {
+ va_list ap;
+
+ va_start(ap, dev_fmt);
+ vscnprintf(cla->dev_id, sizeof(cla->dev_id), dev_fmt, ap);
+ cla->cl.dev_id = cla->dev_id;
+ va_end(ap);
+ }
+
+ return &cla->cl;
+}
+EXPORT_SYMBOL(clkdev_alloc);
+
+int clk_add_alias(const char *alias, const char *alias_dev_name, char *id,
+ struct device *dev)
+{
+ struct clk *r = clk_get(dev, id);
+ struct clk_lookup *l;
+
+ if (IS_ERR(r))
+ return PTR_ERR(r);
+
+ l = clkdev_alloc(r, alias, alias_dev_name);
+ clk_put(r);
+ if (!l)
+ return -ENODEV;
+ clkdev_add(l);
+ return 0;
+}
+EXPORT_SYMBOL(clk_add_alias);
+
+/*
+ * clkdev_drop - remove a clock dynamically allocated
+ */
+void clkdev_drop(struct clk_lookup *cl)
+{
+ mutex_lock(&clocks_mutex);
+ list_del(&cl->node);
+ mutex_unlock(&clocks_mutex);
+ kfree(cl);
+}
+EXPORT_SYMBOL(clkdev_drop);
diff --git a/arch/c6x/kernel/early_printk.c b/arch/c6x/kernel/early_printk.c
new file mode 100644
index 0000000..06a72fd
--- /dev/null
+++ b/arch/c6x/kernel/early_printk.c
@@ -0,0 +1,81 @@
+/*
+ * linux/arch/c6x/kernel/early_printk.c
+ *
+ * Copyright (C) 2011 Texas Instruments Incoporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/console.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/setup.h>
+
+
+static void (*early_write)(const char *s, unsigned n);
+
+static int __initdata keep_early;
+
+static void early_console_write(struct console *con, const char *s, unsigned n)
+{
+ early_write(s, n);
+}
+
+static struct console early_console = {
+ .write = early_console_write,
+ .flags = CON_PRINTBUFFER,
+ .index = -1,
+};
+
+void early_printk(const char *fmt, ...)
+{
+ char buf[512];
+ int n;
+ va_list ap;
+
+ va_start(ap, fmt);
+ n = vscnprintf(buf, sizeof(buf), fmt, ap);
+ early_write(buf, n);
+ va_end(ap);
+}
+
+static int __init setup_early_printk(char *str)
+{
+ if (!str)
+ return 0;
+
+ if (early_write != NULL)
+ return 0;
+
+#ifdef CONFIG_HVC_C6X
+ if (!strncmp(str, "hvc", 3)) {
+ str += 3;
+ early_write = hvc_c6x_early_puts;
+ strcpy(early_console.name, "early_hvc");
+ }
+#endif
+
+ if (strncmp(str, ",keep", 5) == 0)
+ keep_early = 1;
+
+ if (likely(early_write)) {
+
+ if (keep_early)
+ early_console.flags &= ~CON_BOOT;
+ else
+ early_console.flags |= CON_BOOT;
+
+ register_console(&early_console);
+ printk(KERN_INFO "early printk enabled on %s%d\n",
+ early_console.name,
+ early_console.index);
+ }
+
+ return 0;
+}
+early_param("earlyprintk", setup_early_printk);
+
diff --git a/arch/c6x/kernel/entry.S b/arch/c6x/kernel/entry.S
new file mode 100644
index 0000000..e35dd2d
--- /dev/null
+++ b/arch/c6x/kernel/entry.S
@@ -0,0 +1,851 @@
+;
+; linux/arch/c6x/kernel/entry.s
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2004, 2005, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot ([email protected])
+; Updated for 2.6.34: Mark Salter <[email protected]>
+;
+; 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.
+;
+
+ .altmacro
+#define _DEFINE_MACRO(name,args...) .macro name args
+
+#include <linux/sys.h>
+#include <linux/linkage.h>
+#include <asm/thread_info.h>
+#include <asm/asm-offsets.h>
+#include <asm/unistd.h>
+#include <asm/errno.h>
+
+; Registers naming
+#define DP B14
+#define SP B15
+
+#ifndef CONFIG_PREEMPT
+#define resume_kernel restore_all
+#endif
+
+ ;; Entry management functions
+ .global ret_from_exception
+ .global ret_from_interrupt
+
+ ;; Interrupt handlers
+ .global _int4_handler
+ .global _int5_handler
+ .global _int6_handler
+ .global _int7_handler
+ .global _int8_handler
+ .global _int9_handler
+ .global _int10_handler
+ .global _int11_handler
+ .global _int12_handler
+ .global _int13_handler
+ .global _int14_handler
+ .global _int15_handler
+ .global _bad_interrupt
+ .global _nmi_handler
+
+ ;;
+ ;; This defines the normal kernel pt_regs layout.
+ ;;
+_DEFINE_MACRO(SAVE_ALL,__rp,__tsr)
+ STW .D2T2 B0,*SP--[2] ; save original B0
+ MVKL .S2 current_ksp,B0
+ MVKH .S2 current_ksp,B0
+ LDW .D2T2 *B0,B1 ; KSP
+
+ NOP 3
+ STW .D2T2 B1,*+SP[1] ; save original B1
+ XOR .D2 SP,B1,B0 ; (SP ^ KSP)
+ LDW .D2T2 *+SP[1],B1 ; restore B0/B1
+ LDW .D2T2 *++SP[2],B0
+ SHR .S2 B0,THREAD_SHIFT,B0 ; 0 if already using kernel stack
+
+ [B0] STDW .D2T2 SP:DP,*--B1[1] ; user: save user sp/dp on kernel stack
+ [B0] MV .S2 B1,SP ; and switch to kernel stack
+||[!B0] STDW .D2T2 SP:DP,*--SP[1] ; kernel: save on current stack
+
+ SUBAW .D2 SP,2,SP
+
+ ADD .D1X SP,-8,A15
+ || STDW .D2T1 A15:A14,*SP--[16] ; save A15:A14
+
+ STDW .D2T2 B13:B12,*SP--[1]
+ || STDW .D1T1 A13:A12,*A15--[1]
+ || MVC .S2 __rp,B13
+
+ STDW .D2T2 B11:B10,*SP--[1]
+ || STDW .D1T1 A11:A10,*A15--[1]
+ || MVC .S2 CSR,B12
+
+ STDW .D2T2 B9:B8,*SP--[1]
+ || STDW .D1T1 A9:A8,*A15--[1]
+ || MVC .S2 RILC,B11
+ STDW .D2T2 B7:B6,*SP--[1]
+ || STDW .D1T1 A7:A6,*A15--[1]
+ || MVC .S2 ILC,B10
+
+ STDW .D2T2 B5:B4,*SP--[1]
+ || STDW .D1T1 A5:A4,*A15--[1]
+
+ STDW .D2T2 B3:B2,*SP--[1]
+ || STDW .D1T1 A3:A2,*A15--[1]
+ || MVC .S2 __tsr,B5
+
+ STDW .D2T2 B1:B0,*SP--[1]
+ || STDW .D1T1 A1:A0,*A15--[1]
+ || MV .S1X B5,A5
+
+ STDW .D2T2 B31:B30,*SP--[1]
+ || STDW .D1T1 A31:A30,*A15--[1]
+ STDW .D2T2 B29:B28,*SP--[1]
+ || STDW .D1T1 A29:A28,*A15--[1]
+ STDW .D2T2 B27:B26,*SP--[1]
+ || STDW .D1T1 A27:A26,*A15--[1]
+ STDW .D2T2 B25:B24,*SP--[1]
+ || STDW .D1T1 A25:A24,*A15--[1]
+ STDW .D2T2 B23:B22,*SP--[1]
+ || STDW .D1T1 A23:A22,*A15--[1]
+ STDW .D2T2 B21:B20,*SP--[1]
+ || STDW .D1T1 A21:A20,*A15--[1]
+ STDW .D2T2 B19:B18,*SP--[1]
+ || STDW .D1T1 A19:A18,*A15--[1]
+ STDW .D2T2 B17:B16,*SP--[1]
+ || STDW .D1T1 A17:A16,*A15--[1]
+
+ STDW .D2T2 B13:B12,*SP--[1] ; save PC and CSR
+
+ STDW .D2T2 B11:B10,*SP--[1] ; save RILC and ILC
+ STDW .D2T1 A5:A4,*SP--[1] ; save TSR and orig A4
+
+ ;; We left an unused word on the stack just above pt_regs.
+ ;; It is used to save whether or not this frame is due to
+ ;; a syscall. It is cleared here, but the syscall handler
+ ;; sets it to a non-zero value.
+ MVK .L2 0,B1
+ STW .D2T2 B1,*+SP(REGS__END+8) ; clear syscall flag
+ .endm
+
+_DEFINE_MACRO(SAVE_ALL_EXCEPT)
+ SAVE_ALL NRP,NTSR
+ .endm
+
+_DEFINE_MACRO(SAVE_ALL_INT)
+ SAVE_ALL IRP,ITSR
+ .endm
+
+_DEFINE_MACRO(RESTORE_ALL,__rp,__tsr)
+
+ LDDW .D2T2 *++SP[1],B9:B8 ; get TSR (B9)
+ LDDW .D2T2 *++SP[1],B11:B10 ; get RILC (B11) and ILC (B10)
+ LDDW .D2T2 *++SP[1],B13:B12 ; get PC (B13) and CSR (B12)
+
+ ADDAW .D1X SP,30,A15
+
+ LDDW .D1T1 *++A15[1],A17:A16
+ || LDDW .D2T2 *++SP[1],B17:B16
+ LDDW .D1T1 *++A15[1],A19:A18
+ || LDDW .D2T2 *++SP[1],B19:B18
+ LDDW .D1T1 *++A15[1],A21:A20
+ || LDDW .D2T2 *++SP[1],B21:B20
+ LDDW .D1T1 *++A15[1],A23:A22
+ || LDDW .D2T2 *++SP[1],B23:B22
+ LDDW .D1T1 *++A15[1],A25:A24
+ || LDDW .D2T2 *++SP[1],B25:B24
+ LDDW .D1T1 *++A15[1],A27:A26
+ || LDDW .D2T2 *++SP[1],B27:B26
+ LDDW .D1T1 *++A15[1],A29:A28
+ || LDDW .D2T2 *++SP[1],B29:B28
+ LDDW .D1T1 *++A15[1],A31:A30
+ || LDDW .D2T2 *++SP[1],B31:B30
+
+ LDDW .D1T1 *++A15[1],A1:A0
+ || LDDW .D2T2 *++SP[1],B1:B0
+
+ LDDW .D1T1 *++A15[1],A3:A2
+ || LDDW .D2T2 *++SP[1],B3:B2
+ || MVC .S2 B9,__tsr
+ LDDW .D1T1 *++A15[1],A5:A4
+ || LDDW .D2T2 *++SP[1],B5:B4
+ || MVC .S2 B11,RILC
+ LDDW .D1T1 *++A15[1],A7:A6
+ || LDDW .D2T2 *++SP[1],B7:B6
+ || MVC .S2 B10,ILC
+
+ LDDW .D1T1 *++A15[1],A9:A8
+ || LDDW .D2T2 *++SP[1],B9:B8
+ || MVC .S2 B13,__rp
+
+ LDDW .D1T1 *++A15[1],A11:A10
+ || LDDW .D2T2 *++SP[1],B11:B10
+ || MVC .S2 B12,CSR
+
+ LDDW .D1T1 *++A15[1],A13:A12
+ || LDDW .D2T2 *++SP[1],B13:B12
+
+ MV .D2X A15,SP
+ || MVKL .S1 current_ksp,A15
+ MVKH .S1 current_ksp,A15
+ || ADDAW .D1X SP,6,A14
+ STW .D1T1 A14,*A15 ; save kernel stack pointer
+
+ LDDW .D2T1 *++SP[1],A15:A14
+
+ B .S2 __rp ; return from interruption
+ LDDW .D2T2 *+SP[1],SP:DP
+ NOP 4
+ .endm
+
+_DEFINE_MACRO(RESTORE_ALL_EXCEPT)
+ RESTORE_ALL NRP,NTSR
+ .endm
+
+_DEFINE_MACRO(RESTORE_ALL_INT)
+ RESTORE_ALL IRP,ITSR
+ .endm
+
+_DEFINE_MACRO(MASK_SYSCALL)
+ .endm
+
+_DEFINE_MACRO(UNMASK_SYSCALL)
+ .endm
+
+_DEFINE_MACRO(MASK_INT,reg)
+ MVC .S2 CSR,reg
+ CLR .S2 reg,0,0,reg
+ MVC .S2 reg,CSR
+ .endm
+
+ ;; Enable interrupts
+_DEFINE_MACRO(UNMASK_INT,reg)
+ MVC .S2 CSR,reg
+ SET .S2 reg,0,0,reg
+ MVC .S2 reg,CSR
+ .endm
+
+ ;;
+ ;; Call c6x_do_IRQ with the corresponding int number and regs
+ ;;
+_DEFINE_MACRO(CALL_INT,int)
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 c6x_do_IRQ,A0
+ MVKH .S1 c6x_do_IRQ,A0
+ BNOP .S2X A0,1
+ MVK .S1 int,A4
+ ADDAW .D2 SP,2,B4
+ MVKL .S2 ret_from_interrupt,B3
+ MVKH .S2 ret_from_interrupt,B3
+#else
+ CALLP .S2 c6x_do_IRQ,B3
+ || MVK .S1 int,A4
+ || ADDAW .D2 SP,2,B4
+ B .S1 ret_from_interrupt
+ NOP 5
+#endif
+ .endm
+
+_DEFINE_MACRO(GET_THREAD_INFO,reg)
+ SHR .S1X SP,THREAD_SHIFT,reg
+ SHL .S1 reg,THREAD_SHIFT,reg
+ .endm
+
+ .sect ".data"
+
+ .global current_ksp
+current_ksp:
+ .word init_thread_union + THREAD_START_SP
+
+ .sect ".text"
+
+ ;;
+ ;; Jump to schedule() then return to ret_from_exception
+ ;;
+_reschedule:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 schedule,A0
+ MVKH .S1 schedule,A0
+ B .S2X A0
+#else
+ B .S1 schedule
+#endif
+ ADDKPC .S2 ret_from_exception,B3,4
+
+ ;;
+ ;; Called before syscall handler when process is being debugged
+ ;;
+tracesys_on:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 syscall_trace_entry,A0
+ MVKH .S1 syscall_trace_entry,A0
+ B .S2X A0
+#else
+ B .S1 syscall_trace_entry
+#endif
+ ADDKPC .S2 ret_from_syscall_trace,B3,3
+ ADD .S1X 8,SP,A4
+
+ret_from_syscall_trace:
+ ;; tracing returns (possibly new) syscall number
+ MV .D2X A4,B0
+ || MVK .S2 __NR_syscalls,B1
+ CMPLTU .L2 B0,B1,B1
+
+ [!B1] BNOP .S2 ret_from_syscall_function,5
+ || MVK .S1 -ENOSYS,A4
+
+ ;; reload syscall args from (possibly modified) stack frame
+ LDW .D2T2 *+SP(REGS_B4+8),B4
+ LDW .D2T1 *+SP(REGS_A6+8),A6
+ LDW .D2T2 *+SP(REGS_B6+8),B6
+ LDW .D2T1 *+SP(REGS_A8+8),A8
+ LDW .D2T2 *+SP(REGS_B8+8),B8
+
+ ;; Get syscall handler addr from sys_call_table:
+ MVKL .S2 sys_call_table,B1
+ MVKH .S2 sys_call_table,B1
+ LDW .D2T2 *+B1[B0],B0 ; B0 = sys_call_table[__NR_*]
+ MVKL .S2 ret_from_syscall_function,B3
+ MVKH .S2 ret_from_syscall_function,B3
+ NOP 2
+ BNOP .S2 B0,5 ; branch to syscall handler
+ || LDW .D2T1 *+SP(REGS_ORIG_A4+8),A4
+
+syscall_exit_work:
+ AND .D1 _TIF_SYSCALL_TRACE,A2,A0
+ [!A0] BNOP .S1 work_pending,5
+ [A0] B .S2 syscall_trace_exit
+ ADDKPC .S2 resume_userspace,B3,1
+ MVC .S2 CSR,B1
+ SET .S2 B1,0,0,B1
+ MVC .S2 B1,CSR ; enable ints
+
+work_pending:
+ AND .D1 _TIF_NEED_RESCHED,A2,A0
+ [!A0] BNOP .S1 work_notifysig,5
+
+work_resched:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 schedule,A1
+ MVKH .S1 schedule,A1
+ B .S2X A1
+#else
+ B .S2 schedule
+#endif
+ ADDKPC .S2 work_rescheduled,B3,4
+work_rescheduled:
+ ;; make sure we don't miss an interrupt setting need_resched or
+ ;; sigpending between sampling and the rti
+ MASK_INT B2
+ GET_THREAD_INFO A12
+ LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
+ MVK .S1 _TIF_WORK_MASK,A1
+ MVK .S1 _TIF_NEED_RESCHED,A3
+ NOP 2
+ AND .D1 A1,A2,A0
+ || AND .S1 A3,A2,A1
+ [!A0] BNOP .S1 restore_all,5
+ [A1] BNOP .S1 work_resched,5
+
+work_notifysig:
+ B .S2 do_notify_resume
+ LDW .D2T1 *+SP(REGS__END+8),A6 ; syscall flag
+ ADDKPC .S2 resume_userspace,B3,1
+ ADD .S1X 8,SP,A4 ; pt_regs pointer is first arg
+ MV .D2X A2,B4 ; thread_info flags is second arg
+
+ret_from_exception:
+#ifdef CONFIG_PREEMPT
+ MASK_INT B2
+#endif
+ ;;
+ ;; On C64x+, the return way from exception and interrupt
+ ;; is a little bit different
+ ;;
+ret_from_interrupt:
+ ;;
+ ;; Check if we are comming from user mode.
+ ;;
+ LDW .D2T2 *+SP(REGS_TSR+8),B0
+ MVK .S2 0x40,B1
+ NOP 3
+ AND .D2 B0,B1,B0
+ [!B0] BNOP .S2 resume_kernel,5
+
+resume_userspace:
+ ;; make sure we don't miss an interrupt setting need_resched or
+ ;; sigpending between sampling and the rti
+ MASK_INT B2
+ GET_THREAD_INFO A12
+ LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
+ MVK .S1 _TIF_WORK_MASK,A1
+ MVK .S1 _TIF_NEED_RESCHED,A3
+ NOP 2
+ AND .D1 A1,A2,A0
+ [A0] BNOP .S1 work_pending,5
+ BNOP .S1 restore_all,5
+
+ ;;
+ ;; System call handling
+ ;; B0 = syscall number (in sys_call_table)
+ ;; A4,B4,A6,B6,A8,B8 = arguments of the syscall function
+ ;; A4 is the return value register
+ ;;
+system_call_saved:
+ MVK .L2 1,B2
+ STW .D2T2 B2,*+SP(REGS__END+8) ; set syscall flag
+ MVC .S2 B2,ECR ; acknowledge the software exception
+
+ UNMASK_INT B2 ; re-enable global IT
+
+system_call_saved_noack:
+ ;; Check system call number
+ MVK .S2 __NR_syscalls,B1
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 sys_ni_syscall,A0
+#endif
+ CMPLTU .L2 B0,B1,B1
+#ifdef CONFIG_BIG_KERNEL
+ || MVKH .S1 sys_ni_syscall,A0
+#endif
+
+ ;; Check for ptrace
+ GET_THREAD_INFO A12
+
+#ifdef CONFIG_BIG_KERNEL
+ [!B1] B .S2X A0
+#else
+ [!B1] B .S2 sys_ni_syscall
+#endif
+ [!B1] ADDKPC .S2 ret_from_syscall_function,B3,4
+
+ ;; Get syscall handler addr from sys_call_table:
+ MVKL .S2 sys_call_table,B1
+ MVKH .S2 sys_call_table,B1
+ LDW .D2T2 *+B1[B0],B0 ; B0 = _sys_call_table[__NR_*]
+ || LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
+ NOP 4
+ AND .D1 _TIF_SYSCALL_TRACE,A2,A2 ; check for TIF_SYSCALL_TRACE flag
+ [A2] BNOP .S1 tracesys_on,5 ; call syscall_trace_entry before syscall function
+
+ ;; Branch to the corresponding syscall
+ B .S2 B0
+ ADDKPC .S2 ret_from_syscall_function,B3,4
+
+ret_from_syscall_function:
+ STW .D2T1 A4,*+SP(REGS_A4+8) ; save return value in A4
+ ; original A4 is in orig_A4
+syscall_exit:
+ ;; make sure we don't miss an interrupt setting need_resched or
+ ;; sigpending between sampling and the rti
+ MASK_INT B2
+ LDW .D1T1 *+A12(THREAD_INFO_FLAGS),A2
+ MVK .S1 _TIF_ALLWORK_MASK,A1
+ NOP 3
+ AND .D1 A1,A2,A2 ; check for work to do
+ [A2] BNOP .S1 syscall_exit_work,5
+
+restore_all:
+ RESTORE_ALL_EXCEPT
+
+ ;;
+ ;; After a fork we jump here directly from resume,
+ ;; so that A4 contains the previous task structure.
+ ;;
+ .global ret_from_fork
+ret_from_fork:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 schedule_tail,A0
+ MVKH .S1 schedule_tail,A0
+ B .S2X A0
+#else
+ B .S2 schedule_tail
+#endif
+ ADDKPC .S2 ret_from_fork_2,B3,4
+ret_from_fork_2:
+ ;; return 0 in A4 for child process
+ GET_THREAD_INFO A12
+ BNOP .S2 syscall_exit,3
+ MVK .L2 0,B0
+ STW .D2T2 B0,*+SP(REGS_A4+8)
+
+ ;;
+ ;; These are the interrupt handlers, responsible for calling __do_IRQ()
+ ;; int6 is used for syscalls (see _system_call entry)
+ ;;
+_int4_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 4
+
+_int5_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 5
+
+_int6_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 6
+
+_int7_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 7
+
+_int8_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 8
+
+_int9_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 9
+
+_int10_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 10
+
+_int11_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 11
+
+_int12_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 12
+
+_int13_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 13
+
+_int14_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 14
+
+_int15_handler:
+ SAVE_ALL_INT
+ MASK_SYSCALL
+ CALL_INT 15
+
+ ;;
+ ;; Handler for uninitialized and spurious interrupts
+ ;;
+ .global _bad_interrupt
+_bad_interrupt:
+ B .S2 IRP
+ NOP 5
+
+ ;;
+ ;; Handler for NMI (C6x) and exceptions (C64x+)
+ ;;
+ .global _nmi_handler
+_nmi_handler:
+ SAVE_ALL_EXCEPT
+
+ MVC .S2 EFR,B2
+ CMPEQ .L2 1,B2,B2
+ || MVC .S2 TSR,B1
+ CLR .S2 B1,10,10,B1
+ MVC .S2 B1,TSR
+#ifdef CONFIG_BIG_KERNEL
+ [!B2] MVKL .S1 process_exception,A0
+ [!B2] MVKH .S1 process_exception,A0
+ [!B2] B .S2X A0
+#else
+ [!B2] B .S2 process_exception
+#endif
+ [B2] B .S2 system_call_saved
+ [!B2] ADDAW .D2 SP,2,B1
+ [!B2] MV .D1X B1,A4
+ ADDKPC .S2 ret_from_trap,B3,2
+
+ret_from_trap:
+ MV .D2X A4,B0
+ [!B0] BNOP .S2 ret_from_exception,5
+
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S2 system_call_saved_noack,B3
+ MVKH .S2 system_call_saved_noack,B3
+#endif
+
+ LDW .D2T2 *+SP(REGS_B0+8),B0
+ LDW .D2T1 *+SP(REGS_A4+8),A4
+ LDW .D2T2 *+SP(REGS_B4+8),B4
+ LDW .D2T1 *+SP(REGS_A6+8),A6
+ LDW .D2T2 *+SP(REGS_B6+8),B6
+ LDW .D2T1 *+SP(REGS_A8+8),A8
+#ifdef CONFIG_BIG_KERNEL
+ || B .S2 B3
+#else
+ || B .S2 system_call_saved_noack
+#endif
+ LDW .D2T2 *+SP(REGS_B8+8),B8
+ NOP 4
+
+ ;;
+ ;; Jump to schedule() then return to ret_from_isr
+ ;;
+#ifdef CONFIG_PREEMPT
+irq_reschedule:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 schedule,A0
+ MVKH .S1 schedule,A0
+ B .S2X A0
+#else
+ B .S2 schedule
+#endif
+ ADDKPC .S2 ret_from_interrupt,B3,4
+
+resume_kernel:
+ GET_THREAD_INFO A12
+ LDW .D1T1 *+A12(THREAD_INFO_PREEMPT_COUNT),A1
+ NOP 4
+ [A1] BNOP .S2 restore_all,5
+
+preempt_schedule:
+ GET_THREAD_INFO A2
+ LDW .D1T1 *+A2(THREAD_INFO_FLAGS),A1
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S2 preempt_schedule_irq,B0
+ MVKH .S2 preempt_schedule_irq,B0
+ NOP 2
+#else
+ NOP 4
+#endif
+ AND .D1 _TIF_NEED_RESCHED,A1,A1 ; check for TIF_NEED_RESCHED flag
+ [!A1] BNOP .S2 restore_all,5
+#ifdef CONFIG_BIG_KERNEL
+ B .S2 B0
+#else
+ B .S2 preempt_schedule_irq
+#endif
+ ADDKPC .S2 preempt_schedule,B3,4
+#endif
+
+ .global enable_exception
+enable_exception:
+ DINT
+ MVC .S2 TSR,B0
+ MVC .S2 B3,NRP
+ MVK .L2 0xc,B1
+ OR .D2 B0,B1,B0
+ MVC .S2 B0,TSR ; Set GEE and XEN in TSR
+ B .S2 NRP
+ NOP 5
+
+ .global sys_sigaltstack
+sys_sigaltstack:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 do_sigaltstack,A0 ; branch to do_sigaltstack
+ MVKH .S1 do_sigaltstack,A0
+ B .S2X A0
+#else
+ B .S2 do_sigaltstack
+#endif
+ LDW .D2T1 *+SP(REGS_SP+8),A6
+ NOP 4
+
+ ;; kernel_execve
+ .global kernel_execve
+kernel_execve:
+ MVK .S2 __NR_execve,B0
+ SWE
+ BNOP .S2 B3,5
+
+ ;;
+ ;; Special system calls
+ ;; return address is in B3
+ ;;
+ .global sys_clone
+sys_clone:
+ ADD .D1X SP,8,A4
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 c6x_clone,A0
+ MVKH .S1 c6x_clone,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 c6x_clone
+ NOP 5
+#endif
+
+ .global sys_vfork
+sys_vfork:
+ ADD .D1X SP,8,A4
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 c6x_vfork,A0 ; branch to _c6x_vfork(struct pt_regs *regs)
+ MVKH .S1 c6x_vfork,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 c6x_vfork
+ NOP 5
+#endif
+
+ .global sys_rt_sigreturn
+sys_rt_sigreturn:
+ ADD .D1X SP,8,A4
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 do_rt_sigreturn,A0 ; branch to _do_rt_sigreturn
+ MVKH .S1 do_rt_sigreturn,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 do_rt_sigreturn
+ NOP 5
+#endif
+
+ .global sys_execve
+sys_execve:
+ ADDAW .D2 SP,2,B6 ; put regs addr in 4th parameter
+ ; & adjust regs stack addr
+ LDW .D2T2 *+SP(REGS_B4+8),B4
+
+ ;; c6x_execve(char *name, char **argv, char **envp, struct pt_regs *regs)
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 c6x_execve,A0
+ MVKH .S1 c6x_execve,A0
+ B .S2X A0
+#else
+ || B .S2 c6x_execve
+#endif
+ STW .D2T2 B3,*SP--[2]
+ ADDKPC .S2 ret_from_c6x_execve,B3,3
+
+ret_from_c6x_execve:
+ LDW .D2T2 *++SP[2],B3
+ NOP 4
+ BNOP .S2 B3,5
+
+ .global sys_pread_c6x
+sys_pread_c6x:
+ MV .D2X A8,B7
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 sys_pread64,A0
+ MVKH .S1 sys_pread64,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 sys_pread64
+ NOP 5
+#endif
+
+ .global sys_pwrite_c6x
+sys_pwrite_c6x:
+ MV .D2X A8,B7
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 sys_pwrite64,A0
+ MVKH .S1 sys_pwrite64,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 sys_pwrite64
+ NOP 5
+#endif
+
+ .global sys_truncate64_c6x
+sys_truncate64_c6x:
+ MV .D2X A6,B5
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 sys_truncate64,A0
+ MVKH .S1 sys_truncate64,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 sys_truncate64
+ NOP 5
+#endif
+
+ .global sys_ftruncate64_c6x
+sys_ftruncate64_c6x:
+ MV .D2X A6,B5
+#ifdef CONFIG_BIG_KERNEL
+ || MVKL .S1 sys_ftruncate64,A0
+ MVKH .S1 sys_ftruncate64,A0
+ BNOP .S2X A0,5
+#else
+ || B .S2 sys_ftruncate64
+ NOP 5
+#endif
+
+#ifdef __ARCH_WANT_SYSCALL_OFF_T
+;; On Entry
+;; A4 - fd
+;; B4 - offset_lo (LE), offset_hi (BE)
+;; A6 - offset_lo (BE), offset_hi (LE)
+;; B6 - len
+;; A8 - advice
+ .global sys_fadvise64_c6x
+sys_fadvise64_c6x:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 sys_fadvise64,A0
+ MVKH .S1 sys_fadvise64,A0
+ BNOP .S2X A0,2
+#else
+ B .S2 sys_fadvise64
+ NOP 2
+#endif
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ MV .L2 B4,B5
+ || MV .D2X A6,B4
+#else
+ MV .D2X A6,B5
+#endif
+ MV .D1X B6,A6
+ MV .D2X A8,B6
+#endif
+
+;; On Entry
+;; A4 - fd
+;; B4 - offset_lo (LE), offset_hi (BE)
+;; A6 - offset_lo (BE), offset_hi (LE)
+;; B6 - len_lo (LE), len_hi (BE)
+;; A8 - len_lo (BE), len_hi (LE)
+;; B8 - advice
+ .global sys_fadvise64_64_c6x
+sys_fadvise64_64_c6x:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 sys_fadvise64_64,A0
+ MVKH .S1 sys_fadvise64_64,A0
+ BNOP .S2X A0,2
+#else
+ B .S2 sys_fadvise64_64
+ NOP 2
+#endif
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ MV .L2 B4,B5
+ || MV .D2X A6,B4
+ MV .L1 A8,A6
+ || MV .D1X B6,A7
+#else
+ MV .D2X A6,B5
+ MV .L1 A8,A7
+ || MV .D1X B6,A6
+#endif
+ MV .L2 B8,B6
+
+;; On Entry
+;; A4 - fd
+;; B4 - mode
+;; A6 - offset_hi
+;; B6 - offset_lo
+;; A8 - len_hi
+;; B8 - len_lo
+ .global sys_fallocate_c6x
+sys_fallocate_c6x:
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 sys_fallocate,A0
+ MVKH .S1 sys_fallocate,A0
+ BNOP .S2X A0,1
+#else
+ B .S2 sys_fallocate
+ NOP
+#endif
+ MV .D1 A6,A7
+ MV .D1X B6,A6
+ MV .D2X A8,B7
+ MV .D2 B8,B6
diff --git a/arch/c6x/kernel/head.S b/arch/c6x/kernel/head.S
new file mode 100644
index 0000000..af1934c
--- /dev/null
+++ b/arch/c6x/kernel/head.S
@@ -0,0 +1,127 @@
+;
+; linux/arch/c6x/kernel/head.s
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot ([email protected])
+;
+; 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 "tags.h"
+
+ .global _c_int00
+_c_int00:
+ ;; Save tag magic and pointer
+ MV .S1 A4,A10
+ MV .S2 B4,B10
+
+#ifdef CONFIG_XIP_KERNEL
+ ;; Setup a temporary stack to use when calling C code to
+ ;; relocate XIP data.
+ MVKL .S2 _end,B15
+ MVKH .S2 _end,B15
+ ADDAW .D2 B15,4096,B15
+ AND .D2 ~7,B15,B15
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S2 c6x_relocate_xip_data,B0
+ MVKH .S2 c6x_relocate_xip_data,B0
+ B .S2 B0
+ ADDKPC .S2 _ret_from_reloc,B3,4
+_ret_from_reloc:
+#else
+ CALLP .S2 c6x_relocate_xip_data,B3
+#endif
+#else
+ ;; Set the stack pointer
+ MVKL .S2 current_ksp,B0
+ MVKH .S2 current_ksp,B0
+ LDW .D2T2 *B0,B15
+ NOP 4
+ AND .D2 ~7,B15,B15
+#endif
+
+#ifdef CONFIG_MTD_UCLINUX
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S2 c6x_mtd_early_init,B0
+ MVKH .S2 c6x_mtd_early_init,B0
+ B .S2 B0
+ ADDKPC .S2 _ret_from_mtd_early_init,B3,4
+_ret_from_mtd_early_init:
+#else
+ CALLP .S2 c6x_mtd_early_init,B3
+#endif
+#endif
+
+ ;; Set global page pointer in B14
+ MVKL .S2 __bss_start,B14
+ MVKH .S2 __bss_start,B14
+
+ ;; Clear bss area
+ MVKL .S1 __bss_start,A4
+ MVKH .S1 __bss_start,A4
+ MVKL .S1 __bss_stop,A6
+ MVKH .S1 __bss_stop,A6
+
+ CMPLTU .L1 A4,A6,A1
+ [!A1] B .S1 __bss_done
+ ZERO .L2 B4
+ SUB .L1 A6,A4,A5
+ SHR .S1 A5,2,A3
+ NOP 2
+
+ SUB .L2X A3,1,B0
+ || MV .L1X B4,A3
+
+__bss_loop:
+ STW .D1T1 A3,*A4++
+|| [B0] BNOP .S1 __bss_loop,5
+|| [B0] SUB .L2 B0,1,B0
+
+__bss_done:
+
+ ;; Clear GIE and PGIE
+ MVC .S2 CSR,B2
+ CLR .S2 B2,0,1,B2
+ MVC .S2 B2,CSR
+ MVC .S2 TSR,B2
+ CLR .S2 B2,0,1,B2
+ MVC .S2 B2,TSR
+ MVC .S2 ITSR,B2
+ CLR .S2 B2,0,1,B2
+ MVC .S2 B2,ITSR
+ MVC .S2 NTSR,B2
+ CLR .S2 B2,0,1,B2
+ MVC .S2 B2,NTSR
+
+#ifdef CONFIG_XIP_KERNEL
+ ;; Set the stack pointer
+ MVKL .S2 current_ksp,B0
+ MVKH .S2 current_ksp,B0
+ LDW .D2T2 *B0,B15
+ NOP 4
+ AND .D2 ~7,B15,B15
+#endif
+
+ MVKL .S2 TAGS_MAGIC,B0
+ MVKH .S2 TAGS_MAGIC,B0
+ CMPEQ .L1 A10,A0,A0
+ MVKL .S2 c6x_tags_pointer,B1
+ MVKH .S2 c6x_tags_pointer,B1
+ [!A0] MVK .S2 0,B10
+ STW .D2T2 B10,*B1
+
+ ;; Jump to Linux init
+#ifdef CONFIG_BIG_KERNEL
+ MVKL .S1 start_kernel,A0
+ MVKH .S1 start_kernel,A0
+ B .S2X A0
+#else
+ B .S2 start_kernel
+#endif
+ NOP 5
+L1: BNOP .S2 L1,5
+
diff --git a/arch/c6x/kernel/irq.c b/arch/c6x/kernel/irq.c
new file mode 100644
index 0000000..323d119
--- /dev/null
+++ b/arch/c6x/kernel/irq.c
@@ -0,0 +1,119 @@
+/*
+ * linux/arch/c6x/kernel/irq.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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.
+ *
+ * C6x general interrupt handling code.
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/slab.h>
+#include <linux/init.h>
+#include <linux/hardirq.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/io.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/hardirq.h>
+#include <asm/hardware.h>
+
+DECLARE_PER_CPU(struct kernel_stat, kstat);
+
+unsigned long irq_err_count;
+
+#ifndef hw_to_kernel_irq
+#define hw_to_kernel_irq(hw) (hw)
+#endif
+
+static void mask_core_irq(struct irq_data *data)
+{
+ BUG_ON(data->irq >= NR_SYS_IRQS);
+ and_creg(IER, ~(1 << data->irq));
+}
+
+static void unmask_core_irq(struct irq_data *data)
+{
+ BUG_ON(data->irq >= NR_SYS_IRQS);
+ or_creg(IER, 1 << data->irq);
+}
+
+static struct irq_chip core_irq_chip = {
+ .name = "C64x+",
+ .irq_mask = mask_core_irq,
+ .irq_unmask = unmask_core_irq,
+};
+
+void ack_bad_irq(int irq)
+{
+ printk(KERN_ERR "IRQ: spurious interrupt %d\n", irq);
+ irq_err_count++;
+}
+
+asmlinkage void c6x_do_IRQ(unsigned int prio, struct pt_regs *regs)
+{
+ struct pt_regs *old_regs = set_irq_regs(regs);
+
+ irq_enter();
+
+ BUG_ON(prio >= NR_SYS_IRQS);
+
+ generic_handle_irq(hw_to_kernel_irq(prio));
+
+ irq_exit();
+
+ set_irq_regs(old_regs);
+}
+
+void __init init_IRQ(void)
+{
+ int i;
+
+ /* Mask all general IRQs */
+ and_creg(IER, ~0xfff0);
+
+ for (i = 0; i < NR_SYS_IRQS; i++)
+ irq_set_chip_and_handler(i, &core_irq_chip, handle_level_irq);
+
+#ifdef CONFIG_PIC_C64XPLUS
+ init_pic_c64xplus();
+#endif
+
+ /* Clear all general IRQ flags */
+ set_creg(ICR, 0xfff0);
+}
+
+/* This is only necessary to squelch some warning about
+ * IRQs being enabled early. radix_tree_init() leaves
+ * interrupts enabled during early boot when they should
+ * be disabled. None of the individual bits in IER are
+ * enabled so we don't actually get interrupts, just the
+ * warning from init/main.c boot code.
+ */
+int __init __weak arch_early_irq_init(void)
+{
+ /* clear interrupt flags */
+ set_creg(ICR, 0xfff0);
+ local_irq_disable();
+ return 0;
+}
+
+int arch_show_interrupts(struct seq_file *p, int prec)
+{
+ seq_printf(p, "%*s: %10lu\n", prec, "Err", irq_err_count);
+ return 0;
+}
+
diff --git a/arch/c6x/kernel/module.c b/arch/c6x/kernel/module.c
new file mode 100644
index 0000000..8356f99
--- /dev/null
+++ b/arch/c6x/kernel/module.c
@@ -0,0 +1,249 @@
+/*
+ * linux/arch/c6x/kernel/module.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2005, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Thomas Charleux ([email protected])
+ *
+ * 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 handles the architecture-dependent parts of process handling.
+ */
+#include <linux/moduleloader.h>
+#include <linux/elf.h>
+#include <linux/vmalloc.h>
+#include <linux/slab.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/kernel.h>
+#include <linux/bug.h>
+#include <asm/byteorder.h>
+
+#if 0
+#define DEBUGP(fmt...) printk(KERN_INFO fmt)
+#else
+#define DEBUGP(fmt...)
+#endif
+
+void *module_alloc(unsigned long size)
+{
+ if (size == 0)
+ return NULL;
+ return vmalloc_exec(size);
+}
+
+
+/* Free memory returned from module_alloc */
+void module_free(struct module *mod, void *module_region)
+{
+ vfree(module_region);
+ /* FIXME: If module_region == mod->init_region, trim exception
+ table entries. */
+}
+
+/*
+ * finish loading the module
+ */
+int module_finalize(const Elf_Ehdr *hdr,
+ const Elf_Shdr *sechdrs,
+ struct module *me)
+{
+ return 0;
+}
+
+/*
+ * finish clearing the module
+ */
+void module_arch_cleanup(struct module *mod)
+{
+ module_bug_cleanup(mod);
+}
+
+
+/* We don't need anything special. */
+int module_frob_arch_sections(Elf_Ehdr *hdr,
+ Elf_Shdr *sechdrs,
+ char *secstrings,
+ struct module *mod)
+{
+ return 0;
+}
+
+static inline int fixup_pcr(u32 *ip, Elf32_Addr dest, u32 maskbits, int shift)
+{
+ u32 opcode;
+ long ep = (long)ip & ~31;
+ long delta = ((long)dest - ep) >> 2;
+ long mask = (1 << maskbits) - 1;
+
+ if ((delta >> (maskbits - 1)) == 0 ||
+ (delta >> (maskbits - 1)) == -1) {
+ opcode = *ip;
+ opcode &= ~(mask << shift);
+ opcode |= ((delta & mask) << shift);
+ *ip = opcode;
+
+ DEBUGP("REL PCR_S%d[%p] dest[0p] opcode[%08x]\n",
+ maskbits, ip, (void *)dest, opcode);
+
+ return 0;
+ }
+ printk(KERN_ERR "PCR_S%d reloc %p -> %p out of range!\n",
+ maskbits, ip, (void *)dest);
+
+ return -1;
+}
+
+/*
+ * apply a REL relocation
+ */
+int apply_relocate(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ Elf32_Rel *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location;
+ unsigned int i;
+ Elf32_Addr v;
+ Elf_Addr offset = 0;
+
+ DEBUGP("Applying relocate section %u to %u with offset[0x%x]\n", relsec,
+ sechdrs[relsec].sh_info, offset);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset - offset;
+
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rel[i].r_info);
+
+ /* this is the adjustment to be made */
+ v = sym->st_value;
+
+ switch (ELF32_R_TYPE(rel[i].r_info)) {
+ case R_C6000_ABS32:
+ DEBUGP("REL ABS32: [%p] = 0x%x\n", location, v);
+ *location = v;
+ break;
+ case R_C6000_ABS16:
+ DEBUGP("REL ABS16: [%p] = 0x%x\n", location, v);
+ *(u16 *)location = v;
+ break;
+ case R_C6000_ABS8:
+ DEBUGP("REL ABS8: [%p] = 0x%x\n", location, v);
+ *(u8 *)location = v;
+ break;
+ case R_C6000_PCR_S21:
+ if (fixup_pcr(location, v, 21, 7))
+ return -ENOEXEC;
+ break;
+ case R_C6000_PCR_S12:
+ if (fixup_pcr(location, v, 12, 16))
+ return -ENOEXEC;
+ break;
+ case R_C6000_PCR_S10:
+ if (fixup_pcr(location, v, 10, 13))
+ return -ENOEXEC;
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown REL relocation: %u\n",
+ me->name, ELF32_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+
+ return 0;
+}
+
+/*
+ * apply a RELA relocation
+ */
+int apply_relocate_add(Elf32_Shdr *sechdrs,
+ const char *strtab,
+ unsigned int symindex,
+ unsigned int relsec,
+ struct module *me)
+{
+ Elf32_Rela *rel = (void *) sechdrs[relsec].sh_addr;
+ Elf_Sym *sym;
+ u32 *location, opcode;
+ unsigned int i;
+ Elf32_Addr v;
+ Elf_Addr offset = 0;
+
+ DEBUGP("Applying relocate section %u to %u with offset 0x%x\n", relsec,
+ sechdrs[relsec].sh_info, offset);
+
+ for (i = 0; i < sechdrs[relsec].sh_size / sizeof(*rel); i++) {
+ /* This is where to make the change */
+ location = (void *)sechdrs[sechdrs[relsec].sh_info].sh_addr
+ + rel[i].r_offset - offset;
+
+ /* This is the symbol it is referring to. Note that all
+ undefined symbols have been resolved. */
+ sym = (Elf_Sym *)sechdrs[symindex].sh_addr
+ + ELF32_R_SYM(rel[i].r_info);
+
+ /* this is the adjustment to be made */
+ v = sym->st_value + rel[i].r_addend;
+
+ switch (ELF32_R_TYPE(rel[i].r_info)) {
+ case R_C6000_ABS32:
+ DEBUGP("RELA ABS32: [%p] = 0x%x\n", location, v);
+ *location = v;
+ break;
+ case R_C6000_ABS16:
+ DEBUGP("RELA ABS16: [%p] = 0x%x\n", location, v);
+ *(u16 *)location = v;
+ break;
+ case R_C6000_ABS8:
+ DEBUGP("RELA ABS8: [%p] = 0x%x\n", location, v);
+ *(u8 *)location = v;
+ break;
+ case R_C6000_ABS_L16:
+ opcode = *location;
+ opcode &= ~0x7fff80;
+ opcode |= ((v & 0xffff) << 7);
+ DEBUGP("RELA ABS_L16[%p] v[0x%x] opcode[0x%x]\n",
+ location, v, opcode);
+ *location = opcode;
+ break;
+ case R_C6000_ABS_H16:
+ opcode = *location;
+ opcode &= ~0x7fff80;
+ opcode |= ((v >> 9) & 0x7fff80);
+ DEBUGP("RELA ABS_H16[%p] v[0x%x] opcode[0x%x]\n",
+ location, v, opcode);
+ *location = opcode;
+ break;
+ case R_C6000_PCR_S21:
+ if (fixup_pcr(location, v, 21, 7))
+ return -ENOEXEC;
+ break;
+ case R_C6000_PCR_S12:
+ if (fixup_pcr(location, v, 12, 16))
+ return -ENOEXEC;
+ break;
+ case R_C6000_PCR_S10:
+ if (fixup_pcr(location, v, 10, 13))
+ return -ENOEXEC;
+ break;
+ default:
+ printk(KERN_ERR "module %s: Unknown RELA relocation: %u\n",
+ me->name, ELF32_R_TYPE(rel[i].r_info));
+ return -ENOEXEC;
+ }
+ }
+
+ return 0;
+}
+
diff --git a/arch/c6x/kernel/process.c b/arch/c6x/kernel/process.c
new file mode 100644
index 0000000..3aea8b8
--- /dev/null
+++ b/arch/c6x/kernel/process.c
@@ -0,0 +1,349 @@
+/*
+ * linux/arch/c6x/kernel/process.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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 handles the architecture-dependent parts of process handling.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/slab.h>
+#include <linux/user.h>
+#include <linux/reboot.h>
+#include <linux/init_task.h>
+#include <linux/mqueue.h>
+#include <linux/stddef.h>
+#include <linux/module.h>
+#include <linux/tick.h>
+#include <linux/sched.h>
+
+#include <asm/uaccess.h>
+#include <asm/system.h>
+#include <asm/traps.h>
+#include <asm/setup.h>
+#include <asm/pgtable.h>
+#include <asm/pm.h>
+#include <asm/string.h>
+#include <asm/syscalls.h>
+
+#include <mach/board.h> /* for c6x_arch_idle_led() */
+
+static struct signal_struct init_signals = INIT_SIGNALS(init_signals);
+static struct sighand_struct init_sighand = INIT_SIGHAND(init_sighand);
+/*
+ * Initial thread structure.
+ *
+ * We need to make sure that this is THREAD_SIZE aligned due to the
+ * way process stacks are handled. This is done by having a special
+ * "init_task" linker map entry..
+ */
+union thread_union init_thread_union __init_task_data = {
+ INIT_THREAD_INFO(init_task)
+};
+
+/*
+ * Initial task structure.
+ *
+ * All other task structs will be allocated on slabs in fork.c
+ */
+struct task_struct init_task = INIT_TASK(init_task);
+EXPORT_SYMBOL(init_task);
+
+extern asmlinkage void ret_from_fork(void);
+
+/*
+ * power off function, if any
+ */
+void (*pm_power_off)(void);
+EXPORT_SYMBOL(pm_power_off);
+
+/*
+ * power management idle function, if any..
+ */
+void (*pm_idle)(void);
+EXPORT_SYMBOL(pm_idle);
+
+static void default_idle(void)
+{
+#if defined(CONFIG_PM)
+ pwrd_set(PWRD_PD1A);
+#endif
+#ifndef CONFIG_ARCH_SIM
+ do_idle(); /* do nothing until interrupt */
+#endif
+}
+
+/*
+ * The idle loop for C64x
+ */
+void cpu_idle(void)
+{
+ /* endless idle loop with no priority at all */
+ while (1) {
+#ifdef CONFIG_TICK_ONESHOT
+ tick_nohz_stop_sched_tick(1);
+#endif
+ while (!need_resched()) {
+ void (*idle)(void);
+
+ smp_rmb();
+ idle = pm_idle;
+ if (!idle)
+ idle = default_idle;
+ idle();
+ }
+#ifdef CONFIG_TICK_ONESHOT
+ tick_nohz_restart_sched_tick();
+#endif
+ preempt_enable_no_resched();
+ schedule();
+ preempt_disable();
+ }
+}
+
+void machine_restart(char *__unused)
+{
+ while (1)
+ ;
+}
+
+void machine_halt(void)
+{
+ while (1)
+ ;
+}
+
+void machine_power_off(void)
+{
+ while (1)
+ ;
+}
+
+void show_regs(struct pt_regs *regs)
+{
+ printk(KERN_INFO "\n");
+ printk(KERN_INFO "PC: %08lx SP: %08lx\n",
+ regs->pc, regs->sp);
+ printk(KERN_INFO "Status: %08lx ORIG_A4: %08lx\n",
+ regs->csr, regs->orig_a4);
+ printk(KERN_INFO "A0: %08lx B0: %08lx\n",
+ regs->a0, regs->b0);
+ printk(KERN_INFO "A1: %08lx B1: %08lx\n",
+ regs->a1, regs->b1);
+ printk(KERN_INFO "A2: %08lx B2: %08lx\n",
+ regs->a2, regs->b2);
+ printk(KERN_INFO "A3: %08lx B3: %08lx\n",
+ regs->a3, regs->b3);
+ printk(KERN_INFO "A4: %08lx B4: %08lx\n",
+ regs->a4, regs->b4);
+ printk(KERN_INFO "A5: %08lx B5: %08lx\n",
+ regs->a5, regs->b5);
+ printk(KERN_INFO "A6: %08lx B6: %08lx\n",
+ regs->a6, regs->b6);
+ printk(KERN_INFO "A7: %08lx B7: %08lx\n",
+ regs->a7, regs->b7);
+ printk(KERN_INFO "A8: %08lx B8: %08lx\n",
+ regs->a8, regs->b8);
+ printk(KERN_INFO "A9: %08lx B9: %08lx\n",
+ regs->a9, regs->b9);
+ printk(KERN_INFO "A10: %08lx B10: %08lx\n",
+ regs->a10, regs->b10);
+ printk(KERN_INFO "A11: %08lx B11: %08lx\n",
+ regs->a11, regs->b11);
+ printk(KERN_INFO "A12: %08lx B12: %08lx\n",
+ regs->a12, regs->b12);
+ printk(KERN_INFO "A13: %08lx B13: %08lx\n",
+ regs->a13, regs->b13);
+ printk(KERN_INFO "A14: %08lx B14: %08lx\n",
+ regs->a14, regs->dp);
+ printk(KERN_INFO "A15: %08lx B15: %08lx\n",
+ regs->a15, regs->sp);
+ printk(KERN_INFO "A16: %08lx B16: %08lx\n",
+ regs->a16, regs->b16);
+ printk(KERN_INFO "A17: %08lx B17: %08lx\n",
+ regs->a17, regs->b17);
+ printk(KERN_INFO "A18: %08lx B18: %08lx\n",
+ regs->a18, regs->b18);
+ printk(KERN_INFO "A19: %08lx B19: %08lx\n",
+ regs->a19, regs->b19);
+ printk(KERN_INFO "A20: %08lx B20: %08lx\n",
+ regs->a20, regs->b20);
+ printk(KERN_INFO "A21: %08lx B21: %08lx\n",
+ regs->a21, regs->b21);
+ printk(KERN_INFO "A22: %08lx B22: %08lx\n",
+ regs->a22, regs->b22);
+ printk(KERN_INFO "A23: %08lx B23: %08lx\n",
+ regs->a23, regs->b23);
+ printk(KERN_INFO "A24: %08lx B24: %08lx\n",
+ regs->a24, regs->b24);
+ printk(KERN_INFO "A25: %08lx B25: %08lx\n",
+ regs->a25, regs->b25);
+ printk(KERN_INFO "A26: %08lx B26: %08lx\n",
+ regs->a26, regs->b26);
+ printk(KERN_INFO "A27: %08lx B27: %08lx\n",
+ regs->a27, regs->b27);
+ printk(KERN_INFO "A28: %08lx B28: %08lx\n",
+ regs->a28, regs->b28);
+ printk(KERN_INFO "A29: %08lx B29: %08lx\n",
+ regs->a29, regs->b29);
+ printk(KERN_INFO "A30: %08lx B30: %08lx\n",
+ regs->a30, regs->b30);
+ printk(KERN_INFO "A31: %08lx B31: %08lx\n",
+ regs->a31, regs->b31);
+}
+
+
+static void kernel_thread_helper(int dummy, void *arg, int (*fn)(void *))
+{
+ do_exit(fn(arg));
+}
+
+/*
+ * Create a kernel thread
+ */
+int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)
+{
+ struct pt_regs regs;
+
+ /*
+ * copy_thread sets a4 to zero (child return from fork)
+ * so we can't just set things up to directly return to
+ * fn.
+ */
+ memset(&regs, 0, sizeof(regs));
+ regs.b4 = (unsigned long) arg;
+ regs.a6 = (unsigned long) fn;
+ regs.pc = (unsigned long) kernel_thread_helper;
+ local_save_flags(regs.csr);
+ regs.csr |= 1;
+ regs.tsr = 5; /* Set GEE and GIE in TSR */
+
+ /* Ok, create the new process.. */
+ return do_fork(flags | CLONE_VM | CLONE_UNTRACED, -1, &regs, 0, NULL, NULL);
+}
+EXPORT_SYMBOL(kernel_thread);
+
+void flush_thread(void)
+{
+}
+
+void exit_thread(void)
+{
+}
+
+/*
+ * vfork syscall is deprecated but uClibc tests for _NR_vfork as a check
+ * for __libc_vfork() existence. So we provide the syscall even though
+ * __libc_vfork() actually uses the clone syscall.
+ */
+asmlinkage int c6x_vfork(struct pt_regs *regs)
+{
+ return do_fork(CLONE_VFORK | CLONE_VM | SIGCHLD, regs->sp, regs, 0, NULL, NULL);
+}
+
+asmlinkage int c6x_clone(struct pt_regs *regs)
+{
+ unsigned long clone_flags;
+ unsigned long newsp;
+
+ /* syscall puts clone_flags in A4 and usp in B4 */
+ clone_flags = regs->orig_a4;
+ if (regs->b4)
+ newsp = regs->b4;
+ else
+ newsp = regs->sp;
+
+ return do_fork(clone_flags, newsp, regs, 0, (int __user *)regs->a6, (int __user *)regs->b6);
+}
+
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+void start_thread(struct pt_regs *regs, unsigned int pc, unsigned long usp)
+{
+ /*
+ * The binfmt loader will setup a "full" stack, but the C6X
+ * operates an "empty" stack. So we adjust the usp so that
+ * argc doesn't get destroyed if an interrupt is taken before
+ * it is read from the stack.
+ *
+ * NB: Library startup code needs to match this.
+ */
+ usp -= 8;
+
+ set_fs(USER_DS);
+ regs->pc = pc;
+ regs->sp = usp;
+ regs->tsr |= 0x40; /* set user mode */
+ current->thread.usp = usp;
+}
+
+/*
+ * Copy a new thread context in its stack.
+ */
+int copy_thread(unsigned long clone_flags, unsigned long usp,
+ unsigned long ustk_size,
+ struct task_struct *p, struct pt_regs *regs)
+{
+ struct pt_regs *childregs;
+
+ childregs = task_pt_regs(p);
+
+ *childregs = *regs;
+ childregs->a4 = 0;
+
+ if (usp == -1)
+ /* case of __kernel_thread: we return to supervisor space */
+ childregs->sp = (unsigned long)(childregs + 1);
+ else
+ /* Otherwise use the given stack */
+ childregs->sp = usp;
+
+ /* Set usp/ksp */
+ p->thread.usp = childregs->sp;
+ /* switch_to uses stack to save/restore 14 callee-saved regs */
+ thread_saved_ksp(p) = (unsigned long)childregs - 8;
+ p->thread.pc = (unsigned int) ret_from_fork;
+ p->thread.wchan = (unsigned long) ret_from_fork;
+ return 0;
+}
+
+/*
+ * c6x_execve() executes a new program.
+ */
+asmlinkage long c6x_execve(const char __user *name,
+ const char __user *const __user *argv,
+ const char __user *const __user *envp,
+ struct pt_regs *regs)
+{
+ int error;
+ char *filename;
+
+ filename = getname(name);
+ error = PTR_ERR(filename);
+ if (IS_ERR(filename))
+ goto out;
+
+ error = do_execve(filename, argv, envp, regs);
+ putname(filename);
+out:
+ return error;
+}
+
+unsigned long get_wchan(struct task_struct *p)
+{
+ return p->thread.wchan;
+}
diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c
new file mode 100644
index 0000000..fd38463
--- /dev/null
+++ b/arch/c6x/kernel/ptrace.c
@@ -0,0 +1,284 @@
+/*
+ * linux/arch/c6x/kernel/ptrace.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Updated for 2.6.34: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/string.h>
+#include <linux/signal.h>
+#include <linux/mm.h>
+#include <linux/errno.h>
+#include <linux/ptrace.h>
+#include <linux/user.h>
+#include <linux/timer.h>
+#include <linux/security.h>
+#include <linux/tracehook.h>
+#include <linux/uaccess.h>
+
+#include <asm/segment.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/system.h>
+#include <asm/atomic.h>
+#include <asm/cacheflush.h>
+
+/*
+ * does not yet catch signals sent when the child dies.
+ * in exit.c or in signal.c.
+ */
+
+/* Find the stack offset for a register */
+#define PT_REG(reg) ((int)&((struct pt_regs *)0)->reg)
+#define PT_REG_SIZE (sizeof(struct pt_regs))
+
+#ifdef _BIG_ENDIAN
+#define PT_REGPAIR(odd, even) PT_REG(odd), PT_REG(even)
+#else
+#define PT_REGPAIR(odd, even) PT_REG(even), PT_REG(odd)
+#endif
+
+/* Mapping from PT_xxx to the stack offset at which the register is
+ saved. Notice that usp has no stack-slot and needs to be treated
+ specially (see get_reg/put_reg below). */
+
+static int regoff[] = {
+ PT_REGPAIR(tsr, orig_a4),
+ PT_REGPAIR(rilc, ilc),
+ PT_REGPAIR(pc, csr),
+
+ PT_REGPAIR(b17, b16),
+ PT_REGPAIR(b19, b18),
+ PT_REGPAIR(b21, b20),
+ PT_REGPAIR(b23, b22),
+ PT_REGPAIR(b25, b24),
+ PT_REGPAIR(b27, b26),
+ PT_REGPAIR(b29, b28),
+ PT_REGPAIR(b31, b30),
+
+ PT_REGPAIR(b1, b0),
+ PT_REGPAIR(b3, b2),
+ PT_REGPAIR(b5, b4),
+ PT_REGPAIR(b7, b6),
+ PT_REGPAIR(b9, b8),
+ PT_REGPAIR(b11, b10),
+ PT_REGPAIR(b13, b12),
+
+ PT_REGPAIR(a17, a16),
+ PT_REGPAIR(a19, a18),
+ PT_REGPAIR(a21, a20),
+ PT_REGPAIR(a23, a22),
+ PT_REGPAIR(a25, a24),
+ PT_REGPAIR(a27, a26),
+ PT_REGPAIR(a29, a28),
+ PT_REGPAIR(a31, a30),
+
+ PT_REGPAIR(a1, a0),
+ PT_REGPAIR(a3, a2),
+ PT_REGPAIR(a5, a4),
+ PT_REGPAIR(a7, a6),
+ PT_REGPAIR(a9, a8),
+ PT_REGPAIR(a11, a10),
+ PT_REGPAIR(a13, a12),
+
+ PT_REGPAIR(a15, a14),
+ PT_REGPAIR(sp, dp),
+};
+
+/*
+ * Get a register number from live pt_regs for the specified task.
+ */
+static inline long get_reg(struct task_struct *task, int regno)
+{
+ unsigned long *addr;
+ struct pt_regs *regs = task_pt_regs(task);
+
+ if (regno < sizeof(regoff)/sizeof(regoff[0]))
+ addr = (unsigned long *) ((unsigned long) regs + regoff[regno]);
+ else
+ return 0;
+ return *addr;
+}
+
+/*
+ * Write contents of register REGNO in task TASK.
+ */
+static inline int put_reg(struct task_struct *task,
+ int regno,
+ unsigned long data)
+{
+ unsigned long *addr;
+ struct pt_regs *regs = task_pt_regs(task);
+
+ if (regno < sizeof(regoff)/sizeof(regoff[0]))
+ addr = (unsigned long *)((unsigned long) regs + regoff[regno]);
+ else
+ return -1;
+ *addr = data;
+ return 0;
+}
+
+static inline int read_long(struct task_struct *tsk,
+ unsigned long addr,
+ unsigned long *result)
+{
+ *result = *(unsigned long *)addr;
+ return 0;
+}
+
+static inline int write_long(struct task_struct *tsk,
+ unsigned long addr,
+ unsigned long data)
+{
+ *(unsigned long *) addr = data;
+ return 0;
+}
+
+/*
+ * Called by kernel/ptrace.c when detaching.
+ */
+void ptrace_disable(struct task_struct *child)
+{
+ /* nothing to do */
+}
+
+/*
+ * Read the word at offset "off" into the user area. 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;
+ unsigned long index = off/sizeof(unsigned long);
+
+ if (off & 3)
+ return -EIO;
+
+
+ tmp = 0;
+ if (off < PT_REG_SIZE)
+ tmp = get_reg(tsk, index);
+ else
+ return -EIO;
+
+ return put_user(tmp, ret);
+}
+
+/*
+ * Perform ptrace request
+ */
+long arch_ptrace(struct task_struct *child, long request,
+ unsigned long addr, unsigned long data)
+{
+ struct pt_regs *regs, newregs;
+ unsigned long tmp;
+ int ret = 0;
+
+ switch (request) {
+ /*
+ * read word at location "addr" in the child process.
+ */
+ case PTRACE_PEEKTEXT:
+ case PTRACE_PEEKDATA:
+ ret = read_long(child, addr, &tmp);
+ if (!ret)
+ ret = put_user(tmp, (unsigned long __user *) data);
+ break;
+
+ /*
+ * read the word at location "addr" in the user registers.
+ */
+ case PTRACE_PEEKUSR:
+ ret = ptrace_read_user(child, addr, (unsigned long __user *) data);
+ break;
+
+ /*
+ * write the word at location addr.
+ */
+ case PTRACE_POKETEXT:
+ ret = write_long(child, addr, data);
+ flush_icache_range(addr, addr + 4);
+ break;
+
+ case PTRACE_POKEDATA:
+ ret = write_long(child, addr, data);
+ break;
+
+ /*
+ * write the word at location addr in the user registers.
+ */
+ case PTRACE_POKEUSR:
+ ret = -EIO;
+ if (addr & 3 || addr < 0)
+ break;
+
+ if (addr < PT_REG_SIZE)
+ ret = put_reg(child, (int)addr >> 2, data);
+ break;
+
+ /*
+ * get all gp regs from the child.
+ */
+ case PTRACE_GETREGS:
+ regs = task_pt_regs(child);
+ if (copy_to_user((void __user *)data, regs,
+ sizeof(struct pt_regs)))
+ ret = -EFAULT;
+ break;
+
+ /*
+ * set all gp regs in the child.
+ */
+ case PTRACE_SETREGS:
+ ret = -EFAULT;
+ if (copy_from_user(&newregs, (void __user *)data,
+ sizeof(struct pt_regs)) == 0) {
+ regs = task_pt_regs(child);
+ *regs = newregs;
+ ret = 0;
+ }
+ break;
+
+ default:
+ ret = ptrace_request(child, request, addr, data);
+ break;
+ }
+
+ return ret;
+}
+
+/*
+ * handle tracing of system call entry
+ * - return the revised system call number or ULONG_MAX to cause ENOSYS
+ */
+asmlinkage unsigned long syscall_trace_entry(struct pt_regs *regs)
+{
+ if (tracehook_report_syscall_entry(regs))
+ /* tracing decided this syscall should not happen, so
+ * We'll return a bogus call number to get an ENOSYS
+ * error, but leave the original number in
+ * regs->orig_a4
+ */
+ return ULONG_MAX;
+
+ return regs->b0;
+}
+
+/*
+ * handle tracing of system call exit
+ */
+asmlinkage void syscall_trace_exit(struct pt_regs *regs)
+{
+ tracehook_report_syscall_exit(regs, 0);
+}
diff --git a/arch/c6x/kernel/setup.c b/arch/c6x/kernel/setup.c
new file mode 100644
index 0000000..8da373e
--- /dev/null
+++ b/arch/c6x/kernel/setup.c
@@ -0,0 +1,550 @@
+/*
+ * linux/arch/c6x/kernel/setup.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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 handles the architecture-dependent parts of system setup
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/fb.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/console.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/bootmem.h>
+#include <linux/seq_file.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/mm.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/cache.h>
+#include <linux/pm.h>
+#include <linux/dma-mapping.h>
+
+#ifdef CONFIG_MTD_UCLINUX
+#include <linux/mtd/map.h>
+#include <linux/ext2_fs.h>
+#include <linux/cramfs_fs.h>
+#include <linux/romfs_fs.h>
+#endif
+
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/hardware.h>
+#include <asm/sections.h>
+
+#include <mach/board.h>
+
+#ifdef CONFIG_BLK_DEV_INITRD
+#include <linux/initrd.h>
+#include <asm/pgtable.h>
+#endif
+
+#include "tags.h"
+
+unsigned long memory_start;
+unsigned long memory_end;
+
+static char c6x_command_line[COMMAND_LINE_SIZE];
+static const char default_command_line[COMMAND_LINE_SIZE] __section(.cmdline) =
+ CONFIG_CMDLINE;
+static const char *cpu_name, *cpu_voltage, *mmu, *fpu, *soc_rev;
+static char __cpu_rev[5], *cpu_rev;
+static size_t initrd_size = CONFIG_BLK_DEV_RAM_SIZE*1024;
+static unsigned int core_id;
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+unsigned int c6x_platram_start;
+unsigned int c6x_platram_size;
+#endif
+
+#if defined(CONFIG_VGA_CONSOLE)
+struct screen_info screen_info;
+#endif
+
+/*
+ * Mach dep functions
+ */
+
+struct tag_header *c6x_tags_pointer __initdata;
+
+unsigned int ticks_per_ns_scaled;
+EXPORT_SYMBOL(ticks_per_ns_scaled);
+
+unsigned int c6x_core_freq;
+EXPORT_SYMBOL(c6x_core_freq);
+
+static void __init get_cpuinfo(void)
+{
+ unsigned cpu_id, rev_id, csr;
+ struct clk *coreclk = clk_get_sys(NULL, "core");
+ unsigned long core_khz;
+
+ if (!IS_ERR(coreclk))
+ c6x_core_freq = clk_get_rate(coreclk);
+ else {
+ printk(KERN_WARNING
+ "Cannot find core clock frequency. Using 700MHz\n");
+ c6x_core_freq = 700000000;
+ }
+
+ core_khz = c6x_core_freq / 1000;
+
+ ticks_per_ns_scaled =
+ ((uint64_t)core_khz << C6X_NDELAY_SCALE) / 1000000;
+
+ csr = get_creg(CSR);
+ cpu_id = csr >> 24;
+ rev_id = (csr >> 16) & 0xff;
+
+ mmu = "none";
+ cpu_voltage = "unknown";
+
+ switch (cpu_id) {
+ case 0:
+ cpu_name = "C67x";
+ fpu = "yes";
+ break;
+ case 2:
+ cpu_name = "C62x";
+ fpu = "none";
+ break;
+ case 8:
+ cpu_name = "C64x";
+ fpu = "none";
+ break;
+ case 12:
+ cpu_name = "C64x";
+ fpu = "none";
+ break;
+ case 16:
+ cpu_name = "C64x+";
+ cpu_voltage = "1.2";
+ fpu = "none";
+ break;
+ default:
+ cpu_name = "unknown";
+ fpu = "none";
+ }
+
+ if (cpu_id < 16) {
+ switch (rev_id) {
+ case 0x1:
+ if (cpu_id > 8) {
+ cpu_rev = "DM640/DM641/DM642/DM643";
+ cpu_voltage = "1.2 - 1.4";
+ } else {
+ cpu_rev = "C6201";
+ cpu_voltage = "2.5";
+ }
+ break;
+ case 0x2:
+ cpu_rev = "C6201B/C6202/C6211";
+ cpu_voltage = "1.8";
+ break;
+ case 0x3:
+ cpu_rev = "C6202B/C6203/C6204/C6205";
+ cpu_voltage = "1.5";
+ break;
+ case 0x201:
+ cpu_rev = "C6701 revision 0 (early CPU)";
+ cpu_voltage = "1.8";
+ break;
+ case 0x202:
+ cpu_rev = "C6701/C6711/C6712";
+ cpu_voltage = "1.8";
+ break;
+ case 0x801:
+ cpu_rev = "C64x";
+ cpu_voltage = "1.5";
+ break;
+ default:
+ cpu_rev = "unknown";
+ }
+ } else {
+ cpu_rev = __cpu_rev;
+ snprintf(__cpu_rev, sizeof(__cpu_rev), "0x%x", cpu_id);
+ }
+
+ core_id = get_coreid();
+
+ printk(KERN_INFO "CPU%d: %s rev %s, %s volts, %uMHz\n",
+ core_id, cpu_name, cpu_rev,
+ cpu_voltage, c6x_core_freq / 1000000);
+#ifdef C6X_SOC_HAS_CORE_REV
+ soc_rev = arch_compute_silicon_rev(arch_get_silicon_rev());
+#else
+ soc_rev = "unknown";
+#endif
+}
+
+#ifdef CONFIG_TMS320C6X_CACHES_ON
+/*
+ * L1 and L2 caches configuration
+ */
+static void cache_init(void)
+{
+ /* Set L2 caches on the the whole L2 SRAM memory */
+ L2_cache_set_mode(L2MODE_SIZE);
+
+ /* Enable L1 */
+ L1_cache_on();
+}
+#endif /* CONFIG_TMS320C6X_CACHES_ON */
+
+static void cache_set(unsigned int start, unsigned int end)
+{
+#ifdef CONFIG_XIP_KERNEL
+ unsigned long _data_len = (unsigned long)__init_end -
+ (unsigned long)_sdata - 1;
+#endif
+
+ /* Set the whole external memory as non-cacheable */
+ disable_caching(RAM_MEMORY_START,
+ RAM_MEMORY_START + BOARD_RAM_SIZE - 1);
+ /*
+ * Then set the external memory used by this Linux instance cacheable.
+ * DMA coherent memory region will be set as non-cacheable later.
+ */
+ enable_caching(CACHE_REGION_START(start),
+ CACHE_REGION_START(end - 1));
+
+#ifdef CONFIG_XIP_KERNEL
+ /* Also for XIP, make kernel code cacheable if in RAM */
+ if (CONFIG_XIP_KERNEL_TEXT_ADDR >= RAM_MEMORY_START &&
+ CONFIG_XIP_KERNEL_TEXT_ADDR < (RAM_MEMORY_START + BOARD_RAM_SIZE))
+ enable_caching(CACHE_REGION_START(CONFIG_XIP_KERNEL_TEXT_ADDR),
+ CACHE_REGION_START((unsigned long)_data_lma +
+ _data_len));
+#endif
+}
+
+#ifdef CONFIG_XIP_KERNEL
+void __init c6x_relocate_xip_data(void)
+{
+ memcpy(_sdata, _data_lma,
+ (unsigned long)__init_end - (unsigned long)_sdata);
+}
+#endif
+
+/*
+ * Early parsing of the command line
+ */
+static int userdef __initdata;
+
+/* "mem=" parsing. */
+static int __init early_mem(char *p)
+{
+ u32 mem_size;
+
+ if (!p)
+ return -EINVAL;
+
+ mem_size = memparse(p, &p);
+ /* don't remove all of memory when handling "mem={invalid}" */
+ if (mem_size == 0)
+ return -EINVAL;
+
+ userdef = 1;
+ memory_end = PAGE_ALIGN(PAGE_OFFSET + mem_size);
+
+ return 0;
+}
+early_param("mem", early_mem);
+
+/* "memdma=" parsing. */
+static int __init early_memdma(char *p)
+{
+ if (!p)
+ return -EINVAL;
+
+ dma_memory_size = memparse(p, &p);
+ if (*p == '@')
+ dma_memory_start = memparse(p, &p);
+
+ return 0;
+}
+early_param("memdma", early_memdma);
+
+#ifdef CONFIG_BLK_DEV_INITRD
+/* "initrd=" parsing. */
+static int __init early_initrd(char *p)
+{
+ if (!p)
+ return -EINVAL;
+
+ initrd_start = memparse(p, &p);
+ if (*p == ',')
+ initrd_size = memparse(p + 1, &p);
+
+ return 0;
+}
+early_param("initrd", early_initrd);
+#endif /* CONFIG_BLK_DEV_INITRD */
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+/* "platram=" parsing. */
+static int __init early_platram(char *p)
+{
+ if (!p)
+ return -EINVAL;
+
+ c6x_platram_start = memparse(p, &p);
+ if (*p == ',')
+ c6x_platram_size = memparse(p + 1, &p);
+
+ return 0;
+}
+early_param("platram", early_platram);
+#endif
+
+#ifdef CONFIG_MTD_UCLINUX
+static unsigned long get_romfs_size(void *addr)
+{
+#ifdef CONFIG_ROMFS_FS
+ if ((*((unsigned long *)addr) == ROMSB_WORD0) &&
+ (*((unsigned long *)addr + 1) == ROMSB_WORD1))
+ return PAGE_ALIGN(be32_to_cpu(*((unsigned long *)addr + 2)));
+#endif
+
+#ifdef CONFIG_CRAMFS
+ if (*((unsigned long *)addr) == CRAMFS_MAGIC)
+ return PAGE_ALIGN(*((unsigned long *)addr + 1));
+#endif
+
+#if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS)
+ if (le16_to_cpu(*((unsigned short *)addr + 0x21c)) == EXT2_SUPER_MAGIC)
+ return PAGE_ALIGN(le32_to_cpu((*((unsigned long *)addr +
+ 0x101))) * 1024);
+#endif
+
+ return 0;
+}
+
+/*
+ * This is called just before .bss is cleared so that any MTD_UCLINUX
+ * filesystem located in bss can be moved out of the way first.
+ */
+void __init c6x_mtd_early_init(void)
+{
+ unsigned int romfs_size;
+
+ romfs_size = PAGE_ALIGN(get_romfs_size((unsigned *)&__bss_start));
+
+ /* Move ROMFS out of BSS */
+ if (romfs_size)
+ memmove(&_ebss, (int *)&__bss_start, romfs_size);
+}
+
+#endif /* CONFIG_MTD_UCLINUX */
+
+void __init setup_arch(char **cmdline_p)
+{
+ int bootmap_size;
+ struct tag_cmdline *tcmd;
+#if defined(CONFIG_MTD_UCLINUX)
+ unsigned long romfs_size;
+#endif
+
+ if (!c6x_tags_are_valid(c6x_tags_pointer))
+ c6x_tags_pointer = NULL;
+
+ /* interrupts must be masked */
+ local_irq_disable();
+
+ /*
+ * Set the Interrupt Service Table (IST) to the beginning of the
+ * vector table.
+ */
+ set_ist(_vectors_start);
+
+#ifdef CONFIG_TMS320C6X_CACHES_ON
+ /* Perform caches initialization */
+ cache_init();
+#endif
+
+ /* Initialise C6x IRQs */
+ set_creg(IER, 2);
+
+ /* Set peripheral power-down */
+#ifdef CONFIG_PM
+ pwr_pdctl_set(PWR_PDCTL_ALL);
+#endif
+
+ /* Call SOC configuration function */
+ c6x_soc_setup_arch();
+
+ /* Call board configuration function */
+ c6x_board_setup_arch();
+
+ /* Get CPU info */
+ get_cpuinfo();
+
+ /* Memory management */
+ printk(KERN_INFO "Initializing kernel\n");
+
+#if defined(CONFIG_MTD_UCLINUX)
+ romfs_size = get_romfs_size(&_ebss);
+ memory_start = PAGE_ALIGN(((unsigned int) &_ebss) + romfs_size);
+
+ uclinux_ram_map.phys = (unsigned long)&_ebss;
+ uclinux_ram_map.size = romfs_size;
+#else
+ memory_start = PAGE_ALIGN((unsigned int) &_end);
+#endif
+
+ memory_end = PAGE_ALIGN(RAM_MEMORY_START + BOARD_RAM_SIZE);
+
+ init_mm.start_code = (unsigned long) &_stext;
+ init_mm.end_code = (unsigned long) &_etext;
+#if defined(CONFIG_MTD_UCLINUX)
+ init_mm.end_data = (unsigned long) (((unsigned long) &_ebss) +
+ romfs_size);
+ init_mm.brk = (unsigned long) (((unsigned long) &_ebss) +
+ romfs_size);
+#else
+ init_mm.end_data = (unsigned long) &_edata;
+ init_mm.brk = (unsigned long) &_end;
+#endif
+
+ /* Initialize command line */
+ strlcpy(c6x_command_line, default_command_line, COMMAND_LINE_SIZE);
+ *cmdline_p = c6x_command_line;
+
+ /* Let cmdline passed through tag array override CONFIG_CMDLINE */
+ tcmd = c6x_tag_find(c6x_tags_pointer, TAG_CMDLINE);
+ if (tcmd)
+ strlcpy(c6x_command_line, tcmd->cmdline, COMMAND_LINE_SIZE);
+
+ /* parse_early_param needs a boot_command_line */
+ strlcpy(boot_command_line, c6x_command_line, COMMAND_LINE_SIZE);
+
+ parse_early_param();
+
+ if (userdef)
+ printk(KERN_INFO "Physical RAM map changed by user\n");
+
+ /* Set caching of external RAM used by Linux */
+ cache_set(PAGE_OFFSET, memory_end);
+
+ /* Initialize the coherent memory */
+ coherent_mem_init();
+
+ /*
+ * Give all the memory to the bootmap allocator, tell it to put the
+ * boot mem_map at the start of memory
+ */
+ bootmap_size = init_bootmem_node(NODE_DATA(0),
+ memory_start >> PAGE_SHIFT,
+ PAGE_OFFSET >> PAGE_SHIFT,
+ memory_end >> PAGE_SHIFT);
+
+ /*
+ * Free the usable memory, we have to make sure we do not free
+ * the bootmem bitmap so we then reserve it after freeing it :-)
+ */
+ free_bootmem(memory_start, memory_end - memory_start);
+ reserve_bootmem(memory_start, bootmap_size, BOOTMEM_DEFAULT);
+
+ max_low_pfn = PFN_DOWN(memory_end);
+ min_low_pfn = PFN_UP(memory_start);
+ max_mapnr = max_low_pfn - min_low_pfn;
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+ if (c6x_platram_size) {
+ if (c6x_platram_start < (memory_start + bootmap_size) ||
+ (c6x_platram_start + c6x_platram_size) > memory_end) {
+ printk(KERN_ERR "Invalid platram= argument. "
+ "Out of range %p - %p!\n",
+ (void *)memory_start, (void *)memory_end);
+ c6x_platram_size = 0;
+ } else
+ reserve_bootmem(c6x_platram_start, c6x_platram_size,
+ BOOTMEM_DEFAULT);
+ }
+#endif
+
+#ifdef CONFIG_BLK_DEV_INITRD
+ if (initrd_start) {
+ if (initrd_start >= memory_start &&
+ (initrd_start + initrd_size) <= memory_end) {
+ reserve_bootmem(initrd_start, initrd_size,
+ BOOTMEM_DEFAULT);
+ initrd_end = initrd_start+initrd_size;
+ } else {
+ printk(KERN_ERR
+ "initrd is not contained in normal memory\n"
+ "initrd=(0x%08lx:0x%08lx) normal_mem=(%p:%p)\n"
+ "disabling initrd\n",
+ initrd_start, initrd_start + initrd_size,
+ (void *)memory_start, (void *)memory_end);
+ initrd_start = 0;
+ }
+ } else
+ printk(KERN_INFO "no initrd specified\n");
+#endif
+
+ /* Get kmalloc into gear */
+ paging_init();
+
+#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
+ conswitchp = &dummy_con;
+#endif
+}
+
+static int show_cpuinfo(struct seq_file *m, void *v)
+{
+ seq_printf(m,
+ "CPU:\t\t%s\n"
+ "Core revision:\t%s\n"
+ "Core voltage:\t%s\n"
+ "Core id:\t%d\n"
+ "SoC cores:\t%d\n"
+ "MMU:\t\t%s\n"
+ "FPU:\t\t%s\n"
+ "Silicon rev:\t%s\n"
+ "Clocking:\t%uMHz\n"
+ "BogoMips:\t%lu.%02lu\n"
+ "Calibration:\t%lu loops\n",
+ cpu_name, cpu_rev, cpu_voltage, core_id, CORE_NUM, mmu, fpu,
+ soc_rev, (c6x_core_freq + 500000) / 1000000,
+ (loops_per_jiffy/(500000/HZ)),
+ (loops_per_jiffy/(5000/HZ))%100,
+ loops_per_jiffy);
+
+ 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)
+{
+}
+
+const struct seq_operations cpuinfo_op = {
+ c_start,
+ c_stop,
+ c_next,
+ show_cpuinfo
+};
+
diff --git a/arch/c6x/kernel/signal.c b/arch/c6x/kernel/signal.c
new file mode 100644
index 0000000..252c9ec
--- /dev/null
+++ b/arch/c6x/kernel/signal.c
@@ -0,0 +1,384 @@
+/*
+ * linux/arch/c6x/kernel/signal.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * Updated for 2.6.34: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+#include <linux/stddef.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+#include <linux/tracehook.h>
+#include <linux/uaccess.h>
+#include <linux/syscalls.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/ucontext.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+#include <asm/traps.h>
+#include <asm/cacheflush.h>
+
+#define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP)))
+
+/*
+ * Do a signal return, undo the signal stack.
+ */
+
+#define RETCODE_SIZE (9 << 2) /* 9 instructions = 36 bytes */
+
+struct rt_sigframe {
+ struct siginfo __user *pinfo;
+ void __user *puc;
+ struct siginfo info;
+ struct ucontext uc;
+ unsigned long retcode[RETCODE_SIZE >> 2];
+};
+
+static int restore_sigcontext(struct pt_regs *regs, struct sigcontext __user *sc)
+{
+ int err = 0;
+
+#define COPY(x) (err |= __get_user(regs->x, &sc->sc_##x))
+
+ COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8);
+ COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9);
+ COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9);
+
+ COPY(a16); COPY(a17); COPY(a18); COPY(a19);
+ COPY(a20); COPY(a21); COPY(a22); COPY(a23);
+ COPY(a24); COPY(a25); COPY(a26); COPY(a27);
+ COPY(a28); COPY(a29); COPY(a30); COPY(a31);
+ COPY(b16); COPY(b17); COPY(b18); COPY(b19);
+ COPY(b20); COPY(b21); COPY(b22); COPY(b23);
+ COPY(b24); COPY(b25); COPY(b26); COPY(b27);
+ COPY(b28); COPY(b29); COPY(b30); COPY(b31);
+
+ COPY(csr); COPY(pc);
+
+#undef COPY
+
+ return err;
+}
+
+asmlinkage int do_rt_sigreturn(struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame;
+ sigset_t set;
+
+ /*
+ * Since we stacked the signal on a dword boundary,
+ * then 'sp' should be dword aligned here. If it's
+ * not, then the user is trying to mess with us.
+ */
+ if (regs->sp & 7)
+ goto badframe;
+
+ frame = (struct rt_sigframe __user *) ((unsigned long) regs->sp + 8);
+
+ 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(&current->sighand->siglock);
+ current->blocked = set;
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+
+ if (restore_sigcontext(regs, &frame->uc.uc_mcontext))
+ goto badframe;
+
+ return regs->a4;
+
+badframe:
+ force_sig(SIGSEGV, current);
+ return 0;
+}
+
+static int
+setup_sigcontext(struct sigcontext __user *sc, struct pt_regs *regs,
+ unsigned long mask)
+{
+ int err = 0;
+
+ err |= __put_user(mask, &sc->sc_mask);
+
+#define COPY(x) (err |= __put_user(regs->x, &sc->sc_##x))
+
+ COPY(sp); COPY(a4); COPY(b4); COPY(a6); COPY(b6); COPY(a8); COPY(b8);
+ COPY(a0); COPY(a1); COPY(a2); COPY(a3); COPY(a5); COPY(a7); COPY(a9);
+ COPY(b0); COPY(b1); COPY(b2); COPY(b3); COPY(b5); COPY(b7); COPY(b9);
+
+ COPY(a16); COPY(a17); COPY(a18); COPY(a19);
+ COPY(a20); COPY(a21); COPY(a22); COPY(a23);
+ COPY(a24); COPY(a25); COPY(a26); COPY(a27);
+ COPY(a28); COPY(a29); COPY(a30); COPY(a31);
+ COPY(b16); COPY(b17); COPY(b18); COPY(b19);
+ COPY(b20); COPY(b21); COPY(b22); COPY(b23);
+ COPY(b24); COPY(b25); COPY(b26); COPY(b27);
+ COPY(b28); COPY(b29); COPY(b30); COPY(b31);
+
+ COPY(csr); COPY(pc);
+
+#undef COPY
+
+ return err;
+}
+
+static inline void __user *get_sigframe(struct k_sigaction *ka,
+ struct pt_regs *regs,
+ unsigned long framesize)
+{
+ unsigned long sp = regs->sp;
+
+ /*
+ * This is the X/Open sanctioned signal stack switching.
+ */
+ if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags(sp) == 0)
+ sp = current->sas_ss_sp + current->sas_ss_size;
+
+ /*
+ * No matter what happens, 'sp' must be dword
+ * aligned otherwise nasty things will happen
+ */
+ return (void __user *)((sp - framesize) & ~7);
+}
+
+static int setup_rt_frame(int signr, struct k_sigaction *ka, siginfo_t *info,
+ sigset_t *set, struct pt_regs *regs)
+{
+ struct rt_sigframe __user *frame;
+ unsigned long __user *retcode;
+ int err = 0;
+
+ frame = get_sigframe(ka, regs, sizeof(*frame));
+
+ if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
+ goto segv_and_exit;
+
+ err |= __put_user(&frame->info, &frame->pinfo);
+ err |= __put_user(&frame->uc, &frame->puc);
+ err |= copy_siginfo_to_user(&frame->info, info);
+
+ /* Clear all the bits of the ucontext we don't use. */
+ err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext));
+
+ err |= setup_sigcontext(&frame->uc.uc_mcontext, regs, set->sig[0]);
+ err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set));
+
+ /* Set up to return from userspace */
+ retcode = (unsigned long __user *) &frame->retcode;
+ err |= put_user(0x0000002AUL | (__NR_rt_sigreturn << 7), retcode++);
+ /* MVK __NR_rt_sigreturn,B0 */
+ err |= put_user(0x10000000UL, retcode++); /* SWE */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+ err |= put_user(0x00006000UL, retcode++); /* NOP 4 */
+
+ if (err)
+ goto segv_and_exit;
+
+ flush_icache_range((unsigned long) &frame->retcode,
+ (unsigned long) &frame->retcode + RETCODE_SIZE);
+
+ retcode = (unsigned long __user *) &frame->retcode;
+
+ /* Change user context to branch to signal handler */
+ regs->sp = (unsigned long) frame - 8;
+ regs->b3 = (unsigned long) retcode;
+ regs->pc = (unsigned long) ka->sa.sa_handler;
+
+ /* Give the signal number to the handler */
+ regs->a4 = signr;
+
+ /*
+ * For realtime signals we must also set the second and third
+ * arguments for the signal handler.
+ * -- Peter Maydell <[email protected]> 2000-12-06
+ */
+ regs->b4 = (unsigned long)&frame->info;
+ regs->a6 = (unsigned long)&frame->uc;
+
+ return 0;
+
+segv_and_exit:
+ force_sig(SIGSEGV, current);
+ return -EFAULT;
+}
+
+static inline void
+handle_restart(struct pt_regs *regs, struct k_sigaction *ka, int has_handler)
+{
+ switch (regs->a4) {
+ case -ERESTARTNOHAND:
+ if (!has_handler)
+ goto do_restart;
+ regs->a4 = -EINTR;
+ break;
+
+ case -ERESTARTSYS:
+ if (has_handler && !(ka->sa.sa_flags & SA_RESTART)) {
+ regs->a4 = -EINTR;
+ break;
+ }
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+do_restart:
+ regs->a4 = regs->orig_a4;
+ regs->pc -= 4;
+ break;
+ }
+}
+
+/*
+ * handle the actual delivery of a signal to userspace
+ */
+static int handle_signal(int sig,
+ siginfo_t *info, struct k_sigaction *ka,
+ sigset_t *oldset, struct pt_regs *regs,
+ int syscall)
+{
+ int ret;
+
+ /* Are we from a system call? */
+ if (syscall) {
+ /* If so, check system call restarting.. */
+ switch (regs->a4) {
+ case -ERESTART_RESTARTBLOCK:
+ case -ERESTARTNOHAND:
+ regs->a4 = -EINTR;
+ break;
+
+ case -ERESTARTSYS:
+ if (!(ka->sa.sa_flags & SA_RESTART)) {
+ regs->a4 = -EINTR;
+ break;
+ }
+
+ /* fallthrough */
+ case -ERESTARTNOINTR:
+ regs->a4 = regs->orig_a4;
+ regs->pc -= 4;
+ }
+ }
+
+ /* Set up the stack frame */
+ ret = setup_rt_frame(sig, ka, info, oldset, regs);
+ if (ret == 0) {
+ spin_lock_irq(&current->sighand->siglock);
+ sigorsets(&current->blocked, &current->blocked,
+ &ka->sa.sa_mask);
+ if (!(ka->sa.sa_flags & SA_NODEFER))
+ sigaddset(&current->blocked, sig);
+ recalc_sigpending();
+ spin_unlock_irq(&current->sighand->siglock);
+ }
+
+ return ret;
+}
+
+/*
+ * handle a potential signal
+ */
+static void do_signal(struct pt_regs *regs, int syscall)
+{
+ struct k_sigaction ka;
+ siginfo_t info;
+ sigset_t *oldset;
+ int signr;
+
+ /* we want the common case to go fast, which is why we may in certain
+ * cases get here from kernel mode */
+ if (!user_mode(regs))
+ return;
+
+ if (test_thread_flag(TIF_RESTORE_SIGMASK))
+ oldset = &current->saved_sigmask;
+ else
+ oldset = &current->blocked;
+
+ signr = get_signal_to_deliver(&info, &ka, regs, NULL);
+ if (signr > 0) {
+ if (handle_signal(signr, &info, &ka, oldset,
+ regs, syscall) == 0) {
+ /* 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);
+
+ tracehook_signal_handler(signr, &info, &ka, regs, 0);
+ }
+
+ return;
+ }
+
+ /* did we come from a system call? */
+ if (syscall) {
+ /* restart the system call - no handlers present */
+ switch (regs->a4) {
+ case -ERESTARTNOHAND:
+ case -ERESTARTSYS:
+ case -ERESTARTNOINTR:
+ regs->a4 = regs->orig_a4;
+ regs->pc -= 4;
+ break;
+
+ case -ERESTART_RESTARTBLOCK:
+ regs->a4 = regs->orig_a4;
+ regs->b0 = __NR_restart_syscall;
+ regs->pc -= 4;
+ break;
+ }
+ }
+
+ /* if there's no signal to deliver, we just put the saved sigmask
+ * back */
+ if (test_thread_flag(TIF_RESTORE_SIGMASK)) {
+ clear_thread_flag(TIF_RESTORE_SIGMASK);
+ sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
+ }
+}
+
+/*
+ * notification of userspace execution resumption
+ * - triggered by current->work.notify_resume
+ */
+asmlinkage void do_notify_resume(struct pt_regs *regs, u32 thread_info_flags,
+ int syscall)
+{
+ /* deal with pending signal delivery */
+ if (thread_info_flags & ((1 << TIF_SIGPENDING) |
+ (1 << TIF_RESTORE_SIGMASK)))
+ do_signal(regs, syscall);
+
+ if (thread_info_flags & (1 << TIF_NOTIFY_RESUME)) {
+ clear_thread_flag(TIF_NOTIFY_RESUME);
+ tracehook_notify_resume(regs);
+ if (current->replacement_session_keyring)
+ key_replace_session_keyring();
+ }
+}
diff --git a/arch/c6x/kernel/switch_to.S b/arch/c6x/kernel/switch_to.S
new file mode 100644
index 0000000..06a41bb
--- /dev/null
+++ b/arch/c6x/kernel/switch_to.S
@@ -0,0 +1,67 @@
+/*
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Author: Mark Salter ([email protected])
+ *
+ * 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 <asm/asm-offsets.h>
+
+#define SP B15
+
+ /*
+ * void __switch_to(struct thread_info *prev,
+ * struct thread_info *next,
+ * struct task_struct *tsk) ;
+ */
+ .global __switch_to
+__switch_to:
+
+ LDDW .D2T2 *+B4(THREAD_B15_14),B7:B6
+ || MV .L2X A4,B5 ; prev
+ || MV .L1X B4,A5 ; next
+ || MVC .S2 RILC,B1
+
+ STW .D2T2 B3,*+B5(THREAD_PC)
+ || STDW .D1T1 A13:A12,*+A4(THREAD_A13_12)
+ || MVC .S2 ILC,B0
+
+ LDW .D2T2 *+B4(THREAD_PC),B3
+ || LDDW .D1T1 *+A5(THREAD_A13_12),A13:A12
+
+ STDW .D1T1 A11:A10,*+A4(THREAD_A11_10)
+ || STDW .D2T2 B1:B0,*+B5(THREAD_RICL_ICL)
+ || MVKL .S2 current_ksp,B1
+
+ STDW .D2T2 B15:B14,*+B5(THREAD_B15_14)
+ || STDW .D1T1 A15:A14,*+A4(THREAD_A15_14)
+ || MVKH .S2 current_ksp,B1
+
+ ;; Switch to next SP
+ MV .S2 B7,SP
+ || STW .D2T2 B7,*B1
+ || MV .L2 B6,B14
+ || LDDW .D1T1 *+A5(THREAD_RICL_ICL),A1:A0
+
+ STDW .D2T2 B11:B10,*+B5(THREAD_B11_10)
+ || LDDW .D1T1 *+A5(THREAD_A15_14),A15:A14
+
+ STDW .D2T2 B13:B12,*+B5(THREAD_B13_12)
+ || LDDW .D1T1 *+A5(THREAD_A11_10),A11:A10
+
+ B .S2 B3 ; return in next E1
+ || LDDW .D2T2 *+B4(THREAD_B13_12),B13:B12
+
+ LDDW .D2T2 *+B4(THREAD_B11_10),B11:B10
+ NOP
+
+ MV .L2X A0,B0
+ || MV .S1 A6,A4
+
+ MVC .S2 B0,ILC
+ || MV .L2X A1,B1
+
+ MVC .S2 B1,RILC
+
diff --git a/arch/c6x/kernel/sys_c6x.c b/arch/c6x/kernel/sys_c6x.c
new file mode 100644
index 0000000..5d0ee49
--- /dev/null
+++ b/arch/c6x/kernel/sys_c6x.c
@@ -0,0 +1,111 @@
+/*
+ * linux/arch/c6x/kernel/sys_c6x.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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 C6x platform.
+ */
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/smp.h>
+#include <linux/sem.h>
+#include <linux/msg.h>
+#include <linux/shm.h>
+#include <linux/stat.h>
+#include <linux/slab.h>
+#include <linux/mman.h>
+#include <linux/file.h>
+#include <linux/utsname.h>
+#include <linux/module.h>
+#include <linux/syscalls.h>
+#include <linux/mtd/map.h>
+#include <linux/stringify.h>
+#include <linux/uaccess.h>
+
+#include <asm/setup.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/syscalls.h>
+
+#ifdef CONFIG_ACCESS_CHECK
+int _access_ok(unsigned long addr, unsigned long size)
+{
+ if (!size)
+ return 1;
+
+ if (!addr || addr > (0xffffffffUL - (size - 1)))
+ goto _bad_access;
+
+ if (segment_eq(get_fs(), KERNEL_DS))
+ return 1;
+
+ if (memory_start <= addr && (addr + size - 1) < memory_end)
+ return 1;
+
+_bad_access:
+#if 0
+ printk(KERN_CRIT "**Bad access attempt: pid[%d] addr[%p] size[0x%x]\n",
+ current->pid, addr, size);
+#endif
+ return 0;
+}
+EXPORT_SYMBOL(_access_ok);
+#endif
+
+/* sys_cache_sync -- sync caches over given range */
+asmlinkage int sys_cache_sync(unsigned long s, unsigned long e)
+{
+ /* FIXME. Add range checks */
+
+ L1D_cache_block_writeback_invalidate(s, e);
+ L1P_cache_block_invalidate(s, e);
+
+ return 0;
+}
+
+asmlinkage long sys_mmap(unsigned long addr, unsigned long len,
+ unsigned long prot, unsigned long flags,
+ unsigned long fd, off_t offset)
+{
+ if (offset & ~PAGE_MASK)
+ return -EINVAL;
+ return sys_mmap_pgoff(addr, len, prot, flags, fd, offset >> PAGE_SHIFT);
+}
+
+/* Provide the actual syscall number to call mapping. */
+#undef __SYSCALL
+#define __SYSCALL(nr, call) [nr] = (call),
+
+/*
+ * Use trampolines
+ */
+#define sys_pread64 sys_pread_c6x
+#define sys_pwrite64 sys_pwrite_c6x
+#define sys_truncate64 sys_truncate64_c6x
+#define sys_ftruncate64 sys_ftruncate64_c6x
+#define sys_fadvise64 sys_fadvise64_c6x
+#define sys_fadvise64_64 sys_fadvise64_64_c6x
+#define sys_fallocate sys_fallocate_c6x
+
+/* Use sys_mmap_pgoff directly */
+#define sys_mmap2 sys_mmap_pgoff
+
+/*
+ * Note that we can't include <linux/unistd.h> here since the header
+ * guard will defeat us; <asm/unistd.h> checks for __SYSCALL as well.
+ */
+void *sys_call_table[__NR_syscalls] = {
+ [0 ... __NR_syscalls-1] = sys_ni_syscall,
+#include <asm/unistd.h>
+};
+
diff --git a/arch/c6x/kernel/tags.c b/arch/c6x/kernel/tags.c
new file mode 100644
index 0000000..bb1064a
--- /dev/null
+++ b/arch/c6x/kernel/tags.c
@@ -0,0 +1,98 @@
+/*
+ * tags.c
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Author: Mark Salter <[email protected]>
+ *
+ * GPLv2 LICENSE SUMMARY
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * BSD LICENSE
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+#include <linux/types.h>
+
+#include "tags.h"
+
+#define TAG_NEXT(p) \
+ ((struct tag_header *)((char *)p + (((struct tag_header *)p)->size) \
+ + sizeof(struct tag_header)))
+
+struct tag_header *c6x_tag_next(struct tag_header *atag)
+{
+ if (atag->tag == TAG_EOL)
+ return NULL;
+
+ atag = TAG_NEXT(atag);
+ if (atag->tag == TAG_EOL)
+ return NULL;
+
+ return atag;
+}
+
+void *c6x_tag_find(struct tag_header *atag, unsigned int tag)
+{
+ while (atag && atag->tag != TAG_EOL && atag->tag != tag)
+ atag = c6x_tag_next(atag);
+ if (atag && atag->tag == tag)
+ return (void *)((unsigned long)atag + sizeof(*atag));
+ return NULL;
+}
+
+int c6x_tags_are_valid(struct tag_header *atag)
+{
+ if (!atag)
+ return 0;
+
+ if (atag->tag != TAG_SOL || atag->size)
+ return 0;
+
+ return 1;
+}
+
+
diff --git a/arch/c6x/kernel/tags.h b/arch/c6x/kernel/tags.h
new file mode 100644
index 0000000..9c4496d
--- /dev/null
+++ b/arch/c6x/kernel/tags.h
@@ -0,0 +1,82 @@
+/*
+ * tags.h
+ *
+ * This file is provided under a dual BSD/GPLv2 license. When using or
+ * redistributing this file, you may do so under either license.
+ *
+ * Author: Mark Salter <[email protected]>
+ *
+ * GPLv2 LICENSE SUMMARY
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of version 2 of the GNU General Public License 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, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110,
+ * USA
+ *
+ * BSD LICENSE
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * * Neither the name Texas Instruments nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ */
+
+#define TAGS_MAGIC 0x54694265
+
+/* The list must start with an TAG_SOL */
+#define TAG_SOL 0x64000001
+
+/* The list must end with an TAG_EOL */
+#define TAG_EOL 0x64000002
+
+#define TAG_CMDLINE 0x64000003
+
+#ifndef __ASSEMBLY__
+struct tag_header {
+ unsigned int size;
+ unsigned int tag;
+};
+
+struct tag_cmdline {
+ char cmdline[0];
+};
+
+extern int c6x_tags_are_valid(struct tag_header *atag);
+extern struct tag_header *c6x_tag_next(struct tag_header *atag);
+extern void *c6x_tag_find(struct tag_header *atag, unsigned int tag);
+#endif
diff --git a/arch/c6x/kernel/time.c b/arch/c6x/kernel/time.c
new file mode 100644
index 0000000..d969b48
--- /dev/null
+++ b/arch/c6x/kernel/time.c
@@ -0,0 +1,55 @@
+/*
+ * linux/arch/c6x/kernel/time.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/param.h>
+#include <linux/string.h>
+#include <linux/mm.h>
+#include <linux/interrupt.h>
+
+#include <asm/segment.h>
+#include <linux/io.h>
+#include <asm/irq.h>
+#include <asm/timer.h>
+
+#include <linux/timex.h>
+#include <linux/profile.h>
+
+static u32 sched_clock_multiplier;
+#define SCHED_CLOCK_SHIFT 16
+
+/*
+ * scheduler clock - returns current time in nanosec units.
+ */
+u64 sched_clock(void)
+{
+ u64 tsc;
+
+ /* read the TSC value
+ */
+ tsc = get_cycles();
+
+ return (tsc * sched_clock_multiplier) >> SCHED_CLOCK_SHIFT;
+}
+
+void time_init(void)
+{
+ sched_clock_multiplier = ((u64)NSEC_PER_SEC << SCHED_CLOCK_SHIFT) /
+ c6x_core_freq;
+
+ c6x_arch_init_clocksource();
+ c6x_arch_init_clockevents();
+}
+
diff --git a/arch/c6x/kernel/traps.c b/arch/c6x/kernel/traps.c
new file mode 100644
index 0000000..ddb78da
--- /dev/null
+++ b/arch/c6x/kernel/traps.c
@@ -0,0 +1,416 @@
+/*
+ * linux/arch/c6x/kernel/traps.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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.
+ *
+ * Sets up all exception vectors
+ */
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/types.h>
+#include <linux/user.h>
+#include <linux/string.h>
+#include <linux/linkage.h>
+#include <linux/linkage.h>
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kallsyms.h>
+#include <linux/ptrace.h>
+#include <linux/bug.h>
+
+#include <asm/setup.h>
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/traps.h>
+#include <asm/pgtable.h>
+#include <linux/bitops.h>
+#include <asm/irq.h>
+
+void __init trap_init(void)
+{
+ ack_exception(EXCEPT_TYPE_NXF);
+ ack_exception(EXCEPT_TYPE_EXC);
+ ack_exception(EXCEPT_TYPE_IXF);
+ ack_exception(EXCEPT_TYPE_SXF);
+ enable_exception();
+}
+
+void dump_stack(void)
+{
+ unsigned long stack;
+
+ show_stack(current, &stack);
+}
+EXPORT_SYMBOL(dump_stack);
+
+
+void die(char *str, struct pt_regs *fp, int nr)
+{
+ console_verbose();
+ printk(KERN_ERR "%s: %08x\n", str, nr);
+ show_regs(fp);
+
+ if (*((unsigned long *) (PAGE_SIZE + (unsigned long) current))
+ != STACK_MAGIC)
+ printk(KERN_ERR "Corrupted stack page\n");
+ printk(KERN_ERR "Process %s (pid: %d, stackpage=%08lx)\n",
+ current->comm, current->pid, (PAGE_SIZE +
+ (unsigned long) current));
+
+ dump_stack();
+ while (1)
+ ;
+}
+
+static void die_if_kernel(char *str, struct pt_regs *fp, int nr)
+{
+ if (user_mode(fp))
+ return;
+
+ die(str, fp, nr);
+}
+
+
+/* Internal exceptions */
+static struct exception_info iexcept_table[10] = {
+ { "Oops - instruction fetch", SIGBUS, BUS_ADRERR },
+ { "Oops - fetch packet", SIGBUS, BUS_ADRERR },
+ { "Oops - execute packet", SIGILL, ILL_ILLOPC },
+ { "Oops - undefined instruction", SIGILL, ILL_ILLOPC },
+ { "Oops - resource conflict", SIGILL, ILL_ILLOPC },
+ { "Oops - resource access", SIGILL, ILL_PRVREG },
+ { "Oops - privilege", SIGILL, ILL_PRVOPC },
+ { "Oops - loops buffer", SIGILL, ILL_ILLOPC },
+ { "Oops - software exception", SIGILL, ILL_ILLTRP },
+ { "Oops - unknown exception", SIGILL, ILL_ILLOPC }
+};
+
+/* External exceptions */
+static struct exception_info eexcept_table[128] = {
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - external exception", SIGBUS, BUS_ADRERR },
+ { "Oops - CPU memory protection fault", SIGSEGV, SEGV_ACCERR },
+ { "Oops - CPU memory protection fault in L1P", SIGSEGV, SEGV_ACCERR },
+ { "Oops - DMA memory protection fault in L1P", SIGSEGV, SEGV_ACCERR },
+ { "Oops - CPU memory protection fault in L1D", SIGSEGV, SEGV_ACCERR },
+ { "Oops - DMA memory protection fault in L1D", SIGSEGV, SEGV_ACCERR },
+ { "Oops - CPU memory protection fault in L2", SIGSEGV, SEGV_ACCERR },
+ { "Oops - DMA memory protection fault in L2", SIGSEGV, SEGV_ACCERR },
+ { "Oops - EMC CPU memory protection fault", SIGSEGV, SEGV_ACCERR },
+ { "Oops - EMC bus error", SIGBUS, BUS_ADRERR }
+};
+
+static void do_trap(struct exception_info *except_info, struct pt_regs *regs)
+{
+ unsigned long addr = instruction_pointer(regs);
+ siginfo_t info;
+
+ if (except_info->code != TRAP_BRKPT)
+ printk(KERN_DEBUG "TRAP: %s PC[0x%lx] signo[%d] code[%d]\n",
+ except_info->kernel_str, regs->pc,
+ except_info->signo, except_info->code);
+
+ die_if_kernel(except_info->kernel_str, regs, addr);
+
+ info.si_signo = except_info->signo;
+ info.si_errno = 0;
+ info.si_code = except_info->code;
+ info.si_addr = (void __user *)addr;
+
+ force_sig_info(except_info->signo, &info, current);
+}
+
+/*
+ * Process an internal exception (non maskable)
+ */
+static int process_iexcept(struct pt_regs *regs)
+{
+ unsigned int iexcept_report = get_iexcept();
+ unsigned int iexcept_num;
+
+ ack_exception(EXCEPT_TYPE_IXF);
+
+ printk(KERN_ERR "IEXCEPT: PC[0x%lx]\n", regs->pc);
+
+ while (iexcept_report) {
+ iexcept_num = __ffs(iexcept_report);
+ iexcept_report &= ~(1 << iexcept_num);
+ set_iexcept(iexcept_report);
+ if (*(unsigned int *)regs->pc == BKPT_OPCODE) {
+ /* This is a breakpoint */
+ struct exception_info bkpt_exception = {
+ "Oops - undefined instruction",
+ SIGTRAP, TRAP_BRKPT
+ };
+ do_trap(&bkpt_exception, regs);
+ iexcept_report &= ~(0xFF);
+ set_iexcept(iexcept_report);
+ continue;
+ }
+
+ do_trap(&iexcept_table[iexcept_num], regs);
+ }
+ return 0;
+}
+
+/*
+ * Process an external exception (maskable)
+ */
+static void process_eexcept(struct pt_regs *regs)
+{
+ unsigned int eexcept_num;
+ unsigned int bank = 0;
+ int i;
+
+ printk(KERN_ERR "EEXCEPT: PC[0x%lx]\n", regs->pc);
+
+ for (i = 0; i <= 3; i++) {
+ while (IC_MEXPMASK[i]) {
+ __dint();
+ eexcept_num = __ffs(IC_MEXPMASK[i]);
+ IC_MEXPMASK[i] &= ~(1 << eexcept_num); /* ack the external exception */
+ __rint();
+ do_trap(&eexcept_table[eexcept_num +
+ (bank << 5)], regs);
+ }
+ bank++;
+ }
+
+ ack_exception(EXCEPT_TYPE_EXC);
+}
+
+void (*mach_nmi_handler)(struct pt_regs *regs);
+
+/*
+ * Main exception processing
+ */
+asmlinkage int process_exception(struct pt_regs *regs)
+{
+ unsigned int type;
+ unsigned int type_num;
+ unsigned int ie_num = 9; /* default is unknown exception */
+
+ while ((type = get_except_type()) != 0) {
+ type_num = fls(type) - 1;
+
+ switch (type_num) {
+ case EXCEPT_TYPE_NXF:
+ ack_exception(EXCEPT_TYPE_NXF);
+ die("Oops - NMI detected", regs,
+ instruction_pointer(regs));
+ break;
+
+ case EXCEPT_TYPE_IXF:
+ if (process_iexcept(regs))
+ return 1;
+ break;
+
+ case EXCEPT_TYPE_EXC:
+ process_eexcept(regs);
+ break;
+
+ case EXCEPT_TYPE_SXF:
+ ie_num = 8;
+ default:
+ ack_exception(type_num);
+ do_trap(&iexcept_table[ie_num], regs);
+ break;
+ }
+ }
+ return 0;
+}
+
+static int kstack_depth_to_print = 48;
+
+static void show_trace(unsigned long *stack, unsigned long *endstack)
+{
+ unsigned long addr;
+ int i;
+
+ printk(KERN_DEBUG "Call trace:");
+ i = 0;
+ while (stack + 1 <= endstack) {
+ addr = *stack++;
+ /*
+ * If the address is either in the text segment of the
+ * kernel, or in the region which contains vmalloc'ed
+ * memory, it *may* be the address of a calling
+ * routine; if so, print it so that someone tracing
+ * down the cause of the crash will be able to figure
+ * out the call path that was taken.
+ */
+ if (__kernel_text_address(addr)) {
+#ifndef CONFIG_KALLSYMS
+ if (i % 5 == 0)
+ printk(KERN_DEBUG "\n ");
+#endif
+ printk(KERN_DEBUG " [<%08lx>]", addr);
+ print_symbol(" %s\n", addr);
+ i++;
+ }
+ }
+ printk(KERN_DEBUG "\n");
+}
+
+void show_stack(struct task_struct *task, unsigned long *stack)
+{
+ unsigned long *p, *endstack;
+ int i;
+
+ if (!stack) {
+ if (task && task != current)
+ /* We know this is a kernel stack,
+ so this is the start/end */
+ stack = (unsigned long *)thread_saved_ksp(task);
+ else
+ stack = (unsigned long *)&stack;
+ }
+ endstack = (unsigned long *)(((unsigned long)stack + THREAD_SIZE - 1)
+ & -THREAD_SIZE);
+
+ printk(KERN_DEBUG "Stack from %08lx:", (unsigned long)stack);
+ for (i = 0, p = stack; i < kstack_depth_to_print; i++) {
+ if (p + 1 > endstack)
+ break;
+ if (i % 8 == 0)
+ printk(KERN_CONT "\n ");
+ printk(KERN_CONT " %08lx", *p++);
+ }
+ printk(KERN_CONT "\n");
+ show_trace(stack, endstack);
+}
+
+int is_valid_bugaddr(unsigned long addr)
+{
+ return __kernel_text_address(addr);
+}
+
diff --git a/arch/c6x/kernel/vectors.S b/arch/c6x/kernel/vectors.S
new file mode 100644
index 0000000..8e65550
--- /dev/null
+++ b/arch/c6x/kernel/vectors.S
@@ -0,0 +1,81 @@
+;
+; linux/arch/c6x/kernel/vector.s
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2004, 2006, 2009, 2010, 2011 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot ([email protected])
+;
+; 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 section handles all the interrupt vector routines.
+; At RESET the processor sets up the DRAM timing parameters and
+; branches to the label _c_int00 which handles initialization for the C code.
+;
+
+#define ALIGNMENT 5
+
+#ifdef CONFIG_BIG_KERNEL
+ .macro IRQVEC name, handler
+ .align ALIGNMENT
+ .global \name
+\name: STW .D2T1 A0,*B15--[2]
+ || MVKL .S1 \handler,A0
+ MVKH .S1 \handler,A0
+ B .S2X A0
+ LDW .D2T1 *++B15[2],A0
+ NOP 4
+ NOP
+ NOP
+ .endm
+#else /* CONFIG_BIG_KERNEL */
+ .macro IRQVEC name, handler
+ .align ALIGNMENT
+ .global \name
+\name: B .S2 \handler
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+ .endm
+#endif /* CONFIG_BIG_KERNEL */
+
+ .sect ".vectors","ax"
+ .align ALIGNMENT
+#ifdef CONFIG_BIG_KERNEL
+RESET: MVKL .S1 _c_int00,A0 ; branch to _c_int00
+ MVKH .S1 _c_int00,A0
+ B .S2X A0
+#else
+RESET: B .S2 _c_int00
+ NOP
+ NOP
+#endif
+ NOP
+ NOP
+ NOP
+ NOP
+ NOP
+
+
+ IRQVEC NMI,_nmi_handler ; NMI interrupt
+ IRQVEC AINT,_bad_interrupt ; reserved
+ IRQVEC MSGINT,_bad_interrupt ; reserved
+
+ IRQVEC INT4,_int4_handler
+ IRQVEC INT5,_int5_handler
+ IRQVEC INT6,_int6_handler
+ IRQVEC INT7,_int7_handler
+ IRQVEC INT8,_int8_handler
+ IRQVEC INT9,_int9_handler
+ IRQVEC INT10,_int10_handler
+ IRQVEC INT11,_int11_handler
+ IRQVEC INT12,_int12_handler
+ IRQVEC INT13,_int13_handler
+ IRQVEC INT14,_int14_handler
+ IRQVEC INT15,_int15_handler
diff --git a/arch/c6x/kernel/vmlinux.lds.S b/arch/c6x/kernel/vmlinux.lds.S
new file mode 100644
index 0000000..10e6177
--- /dev/null
+++ b/arch/c6x/kernel/vmlinux.lds.S
@@ -0,0 +1,205 @@
+/*
+ * ld script for the c6x kernel
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Mark Salter <[email protected]>
+ */
+#define __VMLINUX_LDS__
+#include <asm-generic/vmlinux.lds.h>
+#include <asm/thread_info.h>
+#include <asm/page.h>
+#include <mach/board.h>
+
+
+ENTRY(_c_int00)
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+jiffies = jiffies_64 + 4;
+#else
+jiffies = jiffies_64;
+#endif
+
+SECTIONS
+{
+#ifdef CONFIG_XIP_KERNEL
+ . = CONFIG_XIP_KERNEL_TEXT_ADDR;
+#else
+ . = PAGE_OFFSET;
+#endif
+
+ .vectors :
+ {
+ VMLINUX_SYMBOL(_vectors_start) = .;
+ *(.vectors)
+ VMLINUX_SYMBOL(_vectors_end) = .;
+ }
+
+#ifdef CONFIG_XIP_KERNEL
+ . = CONFIG_XIP_KERNEL_TEXT_ADDR + 0x400;
+#else
+ . = PAGE_OFFSET + 0x400;
+#endif
+ . = ALIGN(0x1000);
+ .cmdline : { *(.cmdline) }
+
+ /* read-only */
+ .text :
+ {
+ VMLINUX_SYMBOL(_stext) = .;
+ VMLINUX_SYMBOL(_text) = .;
+ TEXT_TEXT
+ SCHED_TEXT
+ LOCK_TEXT
+ IRQENTRY_TEXT
+ KPROBES_TEXT
+#if defined(CONFIG_XIP_KERNEL) || !defined(CONFIG_BIG_KERNEL)
+ VMLINUX_SYMBOL(_sinittext) = .;
+ INIT_TEXT
+ VMLINUX_SYMBOL(_einittext) = .;
+ EXIT_TEXT
+#endif
+ *(.fixup)
+ *(.gnu.warning)
+ }
+
+ EXCEPTION_TABLE(16)
+ NOTES
+
+ RO_DATA_SECTION(32)
+ .rodata_c6x :
+ {
+ *(.const)
+ *(.switch)
+ }
+ . = ALIGN(8);
+ .dynamic :
+ {
+ *(.dynamic)
+ }
+ . = ALIGN(128);
+ VMLINUX_SYMBOL(_rodata_end) = .;
+
+ VMLINUX_SYMBOL(_etext) = .;
+
+#ifdef CONFIG_XIP_KERNEL
+ . = PAGE_OFFSET;
+ .bss : AT(VMLINUX_SYMBOL(_rodata_end))
+#else
+ .bss :
+#endif
+ {
+ VMLINUX_SYMBOL(__bss_start) = .;
+ *(.bss .bss.*)
+ *(COMMON)
+ *(.far)
+ . = ALIGN(128);
+ VMLINUX_SYMBOL(__bss_stop) = .;
+ VMLINUX_SYMBOL(__bss_stop) = .;
+ }
+
+#ifdef CONFIG_XIP_KERNEL
+ .data : AT(LOADADDR(.bss) + SIZEOF(.bss))
+#else
+ .data :
+#endif
+ {
+ VMLINUX_SYMBOL(_sdata) = .;
+ INIT_TASK_DATA(THREAD_SIZE)
+ NOSAVE_DATA
+ PAGE_ALIGNED_DATA(PAGE_SIZE)
+ CACHELINE_ALIGNED_DATA(128)
+ READ_MOSTLY_DATA(128)
+ DATA_DATA
+ CONSTRUCTORS
+ *(.data1)
+ *(.fardata .fardata.*)
+ . = ALIGN(8);
+ }
+#ifdef CONFIG_XIP_KERNEL
+ .neardata : AT(LOADADDR(.data) + SIZEOF(.data))
+#else
+ .neardata :
+#endif
+ {
+ *(.neardata .neardata.* .gnu.linkonce.s.*)
+#ifdef CONFIG_XIP_KERNEL
+ /* The init section should be last, so when we free it, it goes into
+ * the general memory pool, and (hopefully) will decrease fragmentation
+ * a tiny bit. The init section has a _requirement_ that it be
+ * PAGE_SIZE aligned
+ */
+ . = ALIGN(PAGE_SIZE);
+#endif
+ }
+
+ VMLINUX_SYMBOL(_edata) = .;
+ VMLINUX_SYMBOL(_data_lma) = LOADADDR(.data);
+
+ VMLINUX_SYMBOL(__init_begin) = .;
+
+#ifndef CONFIG_XIP_KERNEL
+#ifdef CONFIG_BIG_KERNEL
+ INIT_TEXT_SECTION(PAGE_SIZE)
+
+ /* We have to discard exit text and such at runtime, not link time, to
+ * handle embedded cross-section references (alt instructions, bug
+ * table, eh_frame, etc...). We need all of our .text up front and
+ * .data after it for PCREL call issues.
+ */
+ .exit.text :
+ {
+ EXIT_TEXT
+ }
+ . = ALIGN(16);
+#endif
+ INIT_DATA_SECTION(16)
+ PERCPU(128,PAGE_SIZE)
+
+ .exit.data :
+ {
+ EXIT_DATA
+ }
+#else
+ .init.data : AT(LOADADDR(.neardata) + SIZEOF(.neardata))
+ {
+ VMLINUX_SYMBOL(_sinitdata) = .;
+ INIT_DATA
+ INIT_SETUP(16)
+ INIT_CALLS
+ CON_INITCALL
+ SECURITY_INITCALL
+ INIT_RAM_FS
+ . = ALIGN(8);
+ VMLINUX_SYMBOL(__per_cpu_load) = .;
+ VMLINUX_SYMBOL(__per_cpu_start) = .;
+ *(.data.percpu.first)
+ *(.data.percpu.page_aligned)
+ *(.data.percpu)
+ *(.data.percpu.shared_aligned)
+ VMLINUX_SYMBOL(__per_cpu_end) = .;
+
+ EXIT_DATA
+
+ . = ALIGN(8);
+ }
+#endif
+ . = ALIGN(PAGE_SIZE);
+
+ VMLINUX_SYMBOL(__init_end) = .;
+
+ /*
+ * _ebss is used solely for CONFIG_MTD_UCLINUX support.
+ * Traditionally, _ebss (end of .bss) would be the end of a kernel
+ * image where a ROMFS could be appended. In this case, .bss is
+ * elsewhere but we define _ebss at the end.
+ */
+ VMLINUX_SYMBOL(_ebss) = .;
+
+ VMLINUX_SYMBOL(_end) = . ;
+
+ STABS_DEBUG
+
+ DWARF_DEBUG
+
+ DISCARDS
+}
--
1.6.2.5

2011-05-11 21:09:54

by Mark Salter

[permalink] [raw]
Subject: [PATCH 10/16] C6X: add mm files

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/mm/Makefile | 10 ++
arch/c6x/mm/dma-coherent.c | 342 ++++++++++++++++++++++++++++++++++++++++++++
arch/c6x/mm/init.c | 115 +++++++++++++++
3 files changed, 467 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/mm/Makefile
create mode 100644 arch/c6x/mm/dma-coherent.c
create mode 100644 arch/c6x/mm/init.c

diff --git a/arch/c6x/mm/Makefile b/arch/c6x/mm/Makefile
new file mode 100644
index 0000000..75bf2af
--- /dev/null
+++ b/arch/c6x/mm/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for the linux c6x-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+obj-y := init.o dma-coherent.o
diff --git a/arch/c6x/mm/dma-coherent.c b/arch/c6x/mm/dma-coherent.c
new file mode 100644
index 0000000..d466869
--- /dev/null
+++ b/arch/c6x/mm/dma-coherent.c
@@ -0,0 +1,342 @@
+/*
+ * linux/arch/c6x/mm/dma-coherent.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot <[email protected]>
+ *
+ * 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.
+ *
+ * Using code pulled from ARM
+ * Copyright (C) 2000-2004 Russell King
+ *
+ */
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/vmalloc.h>
+#include <linux/interrupt.h>
+#include <linux/errno.h>
+#include <linux/scatterlist.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/device.h>
+#include <linux/wait.h>
+
+#include <asm-generic/dma-coherent.h>
+#include <linux/dma-mapping.h>
+
+#include <asm/io.h>
+#include <asm/cache.h>
+#include <asm/pgtable.h>
+#include <asm/pgalloc.h>
+
+/*
+ * DMA coherent memory management, can be redefined using the memdma=
+ * kernel command line
+ */
+
+/* by default at the end of the Linux physical memory */
+unsigned long dma_memory_start;
+/* none by default */
+unsigned long dma_memory_size;
+
+static u32 dma_page_heap;
+static u32 dma_page_top;
+
+static DEFINE_SPINLOCK(dma_mem_lock);
+
+/*
+ * Return a DMA coherent and contiguous memory chunk from the DMA memory
+ */
+static inline u32 __dma_alloc_coherent(size_t size, gfp_t gfp)
+{
+ u32 paddr;
+
+ if ((dma_page_heap + size) > dma_page_top)
+ return -1;
+
+ paddr = dma_page_heap;
+ dma_page_heap += size;
+
+ return paddr;
+}
+
+/*
+ * Return a standard contigous memory chunk
+ */
+static inline u32 __dma_alloc_coherent_stdmem(size_t size, gfp_t gfp)
+{
+ void *virt;
+
+ virt = kmalloc(size, gfp);
+ if (!virt)
+ return -1;
+
+ return virt_to_phys(virt);
+}
+
+/*
+ * Allocate DMA-coherent memory space and return both the kernel remapped
+ * virtual and bus address for that space.
+ *
+ * Note that this does *not* zero the allocated area!
+ */
+void *
+dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *handle, gfp_t gfp)
+{
+ u32 paddr;
+ void __iomem *virt;
+
+ if (in_interrupt())
+ BUG();
+
+ /* Round up to a page */
+ size = PAGE_ALIGN(size);
+
+ spin_lock_irq(&dma_mem_lock);
+
+ /* Check if we have a DMA memory */
+ if (dma_page_heap)
+ paddr = __dma_alloc_coherent(size, gfp);
+ else
+ /* Otherwise do an allocation using standard allocator */
+ paddr = __dma_alloc_coherent_stdmem(size, gfp);
+
+ spin_unlock_irq(&dma_mem_lock);
+
+ if (paddr == -1)
+ return NULL;
+
+ if (handle)
+ *handle = __phys_to_bus(paddr);
+
+ /*
+ * In a near future we can expect having a partial MMU with
+ * chaching attributes
+ */
+ virt = ioremap_nocache(paddr, size);
+ if (!virt)
+ return NULL;
+
+ /*
+ * We need to ensure that there are no cachelines in use, or
+ * worse dirty in this area.
+ */
+ L2_cache_block_invalidate(paddr, paddr + size);
+
+ return (void *) virt;
+}
+EXPORT_SYMBOL(dma_alloc_coherent);
+
+/*
+ * Free a DMA coherent and contiguous memory chunk from the DMA memory
+ */
+static inline void __dma_free_coherent(size_t size, dma_addr_t dma_handle)
+{
+ /* Do nothing (we do not have real memory alloctor here) */
+}
+
+/*
+ * Free a standard contigous memory chunk
+ */
+static inline void __dma_free_coherent_stdmem(size_t size, dma_addr_t dma_handle)
+{
+ void *virt = bus_to_virt(dma_handle);
+
+ kfree(virt);
+}
+
+/*
+ * Free a page as defined by the above mapping.
+ * Must not be called with IRQs disabled.
+ */
+void
+dma_free_coherent(struct device *dev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+ if (in_interrupt())
+ BUG();
+
+ /* Check if we have a DMA memory */
+ if (dma_page_heap)
+ __dma_free_coherent(size, dma_handle);
+ else
+ /* Otherwise use standard allocator */
+ __dma_free_coherent_stdmem(size, dma_handle);
+
+ iounmap(vaddr);
+}
+EXPORT_SYMBOL(dma_free_coherent);
+
+int
+__dma_is_coherent(struct device *dev, dma_addr_t handle)
+{
+ u32 paddr;
+
+ /* If we do not have DMA memory */
+ if (!dma_page_heap)
+ return 0;
+
+ paddr = __bus_to_phys(handle);
+
+ /*
+ * If the address is in the DMA memory range, the memory
+ * is coherent.
+ */
+ if ((paddr >= dma_memory_start) &&
+ (paddr < dma_page_top))
+ return 1;
+
+ return 0;
+}
+EXPORT_SYMBOL(__dma_is_coherent);
+
+/*
+ * Make an area consistent for devices.
+ * Note: Drivers should NOT use this function directly, as it will break
+ * platforms with CONFIG_DMABOUNCE.
+ * Use the driver DMA support - see dma-mapping.h (dma_sync_*)
+ */
+void __dma_single_cpu_to_dev(const void *kaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ unsigned long paddr;
+
+ BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
+
+ paddr = __pa(kaddr);
+ switch (dir) {
+ case DMA_FROM_DEVICE:
+ L2_cache_block_invalidate(paddr, paddr + size);
+ break;
+ case DMA_TO_DEVICE:
+ L2_cache_block_writeback(paddr, paddr + size);
+ break;
+ case DMA_BIDIRECTIONAL:
+ L2_cache_block_writeback_invalidate(paddr, paddr + size);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(__dma_single_cpu_to_dev);
+
+void __dma_single_dev_to_cpu(const void *kaddr, size_t size,
+ enum dma_data_direction dir)
+{
+ BUG_ON(!virt_addr_valid(kaddr) || !virt_addr_valid(kaddr + size - 1));
+
+ /* don't bother invalidating if DMA to device */
+ if (dir != DMA_TO_DEVICE) {
+ unsigned long paddr = __pa(kaddr);
+ L2_cache_block_invalidate(paddr, paddr + size);
+ }
+}
+EXPORT_SYMBOL(__dma_single_dev_to_cpu);
+
+void __dma_page_cpu_to_dev(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ unsigned long paddr;
+
+ paddr = page_to_phys(page) + off;
+ switch (dir) {
+ case DMA_FROM_DEVICE:
+ L2_cache_block_invalidate(paddr, paddr + size);
+ break;
+ case DMA_TO_DEVICE:
+ L2_cache_block_writeback(paddr, paddr + size);
+ break;
+ case DMA_BIDIRECTIONAL:
+ L2_cache_block_writeback_invalidate(paddr, paddr + size);
+ break;
+ default:
+ break;
+ }
+}
+EXPORT_SYMBOL(__dma_page_cpu_to_dev);
+
+void __dma_page_dev_to_cpu(struct page *page, unsigned long off,
+ size_t size, enum dma_data_direction dir)
+{
+ unsigned long paddr = page_to_phys(page) + off;
+
+ /* don't bother invalidating if DMA to device */
+ if (dir != DMA_TO_DEVICE)
+ L2_cache_block_invalidate(paddr, paddr + size);
+}
+EXPORT_SYMBOL(__dma_page_dev_to_cpu);
+
+/*
+ * Initialise the coherent memory and its allocator
+ */
+int coherent_mem_init(void)
+{
+ /*
+ * Define the (DMA) coherent memory
+ */
+ if (dma_memory_size != 0) {
+
+ /* Round it to the (upper) MAR granularity */
+ dma_memory_size = CACHE_REGION_END(dma_memory_size);
+
+ if (!dma_memory_start) {
+ /*
+ * Take the coherent memory from the end of the physical
+ * memory and round it to the lower MAR.
+ * We may waste some cacheable memory if memory_end is not
+ * aligned on a MAR region.
+ */
+ dma_memory_start =
+ CACHE_REGION_START(memory_end - dma_memory_size);
+
+ /* Then remove the coherent memory from the paged one */
+ memory_end = dma_memory_start;
+
+
+ } else {
+ /* Align it on MAR */
+ dma_memory_start = CACHE_REGION_START(dma_memory_start);
+
+ /*
+ * Check if the defined coherent memory is within the paged
+ * memory. If so remove the corresponding memory
+ */
+ if ((dma_memory_start < memory_end) && (dma_memory_start > memory_start))
+ memory_end = dma_memory_start;
+ }
+
+ printk(KERN_INFO "Coherent memory (DMA) region start=0x%lx size=0x%lx\n",
+ dma_memory_start,
+ dma_memory_size);
+
+ /*
+ * We need to ensure that there are no cachelines in use, or
+ * worse dirty in this area.
+ */
+ L2_cache_block_writeback(dma_memory_start,
+ dma_memory_start + dma_memory_size - 1);
+
+ /* Make this memory coherent (so non-cacheable) */
+ disable_caching(dma_memory_start,
+ dma_memory_start + dma_memory_size - 1);
+
+ printk(KERN_INFO "disabling caching for 0x%lx to 0x%lx\n",
+ dma_memory_start,
+ dma_memory_start + dma_memory_size - 1);
+
+ /* The allocator starts here */
+ dma_page_heap = dma_memory_start;
+
+ /* And finish here */
+ dma_page_top = PAGE_ALIGN(dma_memory_start + dma_memory_size);
+ }
+
+ return 0;
+}
+
diff --git a/arch/c6x/mm/init.c b/arch/c6x/mm/init.c
new file mode 100644
index 0000000..520bcdc
--- /dev/null
+++ b/arch/c6x/mm/init.c
@@ -0,0 +1,115 @@
+/*
+ * linux/arch/c6x/mm/init.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/swap.h>
+#include <linux/bootmem.h>
+#ifdef CONFIG_BLK_DEV_RAM
+#include <linux/blkdev.h>
+#endif
+#include <linux/initrd.h>
+
+#include <asm/sections.h>
+
+/*
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+unsigned long empty_zero_page;
+EXPORT_SYMBOL(empty_zero_page);
+
+/*
+ * paging_init() continues the virtual memory environment setup which
+ * was begun by the code in arch/head.S.
+ * The parameters are pointers to where to stick the starting and ending
+ * addresses of available kernel virtual memory.
+ */
+void __init paging_init(void)
+{
+ struct pglist_data *pgdat = NODE_DATA(0);
+ unsigned long zones_size[MAX_NR_ZONES] = {0, };
+
+ empty_zero_page = (unsigned long) alloc_bootmem_pages(PAGE_SIZE);
+ memset((void *)empty_zero_page, 0, PAGE_SIZE);
+
+ /*
+ * Set up user data space
+ */
+ set_fs(KERNEL_DS);
+
+ /*
+ * Define zones
+ */
+ zones_size[ZONE_NORMAL] = (memory_end - PAGE_OFFSET) >> PAGE_SHIFT;
+ pgdat->node_zones[ZONE_NORMAL].zone_start_pfn =
+ __pa(PAGE_OFFSET) >> PAGE_SHIFT;
+
+ free_area_init(zones_size);
+}
+
+void __init mem_init(void)
+{
+ int codek, datak;
+ unsigned long tmp;
+ unsigned long len = memory_end - memory_start;
+
+ high_memory = (void *)(memory_end & PAGE_MASK);
+
+ /* this will put all memory onto the freelists */
+ totalram_pages = free_all_bootmem();
+
+ codek = (_etext - _stext) >> 10;
+ datak = (_ebss - _sdata) >> 10;
+
+ tmp = nr_free_pages() << PAGE_SHIFT;
+ printk(KERN_INFO "Memory: %luk/%luk RAM (%dk kernel code, %dk data)\n",
+ tmp >> 10, len >> 10, codek, datak);
+}
+
+#ifdef CONFIG_BLK_DEV_INITRD
+void __init free_initrd_mem(unsigned long start, unsigned long end)
+{
+ int pages = 0;
+ for (; start < end; start += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(start));
+ init_page_count(virt_to_page(start));
+ free_page(start);
+ totalram_pages++;
+ pages++;
+ }
+ printk(KERN_INFO "Freeing initrd memory: %luk freed\n",
+ (pages * PAGE_SIZE) >> 10);
+}
+#endif
+
+void __init free_initmem(void)
+{
+ unsigned long addr;
+
+ /*
+ * The following code should be cool even if these sections
+ * are not page aligned.
+ */
+ addr = PAGE_ALIGN((unsigned long)(__init_begin));
+
+ /* next to check that the page we free is not a partial page */
+ for (; addr + PAGE_SIZE < (unsigned long)(__init_end);
+ addr += PAGE_SIZE) {
+ ClearPageReserved(virt_to_page(addr));
+ init_page_count(virt_to_page(addr));
+ free_page(addr);
+ totalram_pages++;
+ }
+ printk(KERN_INFO "Freeing unused kernel memory: %dK freed\n",
+ (int) ((addr - PAGE_ALIGN((long) &__init_begin)) >> 10));
+}
--
1.6.2.5

2011-05-11 21:06:55

by Mark Salter

[permalink] [raw]
Subject: [PATCH 11/16] C6X: add lib files

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/lib/Makefile | 10 +
arch/c6x/lib/csum_64plus.S | 408 +++++++++++++++++++++++++++++++++++++++++
arch/c6x/lib/divi.S | 51 +++++
arch/c6x/lib/divremi.S | 45 +++++
arch/c6x/lib/divremu.S | 86 +++++++++
arch/c6x/lib/divu.S | 97 ++++++++++
arch/c6x/lib/divull.c | 332 +++++++++++++++++++++++++++++++++
arch/c6x/lib/llshl.S | 36 ++++
arch/c6x/lib/llshr.S | 36 ++++
arch/c6x/lib/llshru.S | 36 ++++
arch/c6x/lib/memcmp.c | 26 +++
arch/c6x/lib/memcpy_64plus.S | 45 +++++
arch/c6x/lib/memmove.c | 32 ++++
arch/c6x/lib/memset.c | 25 +++
arch/c6x/lib/mpyll.S | 47 +++++
arch/c6x/lib/negll.S | 29 +++
arch/c6x/lib/pop_rts.S | 30 +++
arch/c6x/lib/push_rts.S | 28 +++
arch/c6x/lib/remi.S | 62 ++++++
arch/c6x/lib/remu.S | 81 ++++++++
arch/c6x/lib/strasgi.S | 88 +++++++++
arch/c6x/lib/strasgi_64plus.S | 37 ++++
22 files changed, 1667 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/lib/Makefile
create mode 100644 arch/c6x/lib/csum_64plus.S
create mode 100644 arch/c6x/lib/divi.S
create mode 100644 arch/c6x/lib/divremi.S
create mode 100644 arch/c6x/lib/divremu.S
create mode 100644 arch/c6x/lib/divu.S
create mode 100644 arch/c6x/lib/divull.c
create mode 100644 arch/c6x/lib/llshl.S
create mode 100644 arch/c6x/lib/llshr.S
create mode 100644 arch/c6x/lib/llshru.S
create mode 100644 arch/c6x/lib/memcmp.c
create mode 100644 arch/c6x/lib/memcpy_64plus.S
create mode 100644 arch/c6x/lib/memmove.c
create mode 100644 arch/c6x/lib/memset.c
create mode 100644 arch/c6x/lib/mpyll.S
create mode 100644 arch/c6x/lib/negll.S
create mode 100644 arch/c6x/lib/pop_rts.S
create mode 100644 arch/c6x/lib/push_rts.S
create mode 100644 arch/c6x/lib/remi.S
create mode 100644 arch/c6x/lib/remu.S
create mode 100644 arch/c6x/lib/strasgi.S
create mode 100644 arch/c6x/lib/strasgi_64plus.S

diff --git a/arch/c6x/lib/Makefile b/arch/c6x/lib/Makefile
new file mode 100644
index 0000000..5c095e8
--- /dev/null
+++ b/arch/c6x/lib/Makefile
@@ -0,0 +1,10 @@
+#
+# Makefile for arch/c6x/lib/
+#
+
+lib-y := memcmp.o memmove.o memset.o \
+ divu.o divi.o pop_rts.o push_rts.o remi.o remu.o \
+ strasgi.o llshru.o llshr.o llshl.o negll.o mpyll.o divull.o \
+ divremi.o divremu.o
+
+lib-$(CONFIG_TMS320C64XPLUS) += csum_64plus.o memcpy_64plus.o strasgi_64plus.o
diff --git a/arch/c6x/lib/csum_64plus.S b/arch/c6x/lib/csum_64plus.S
new file mode 100644
index 0000000..a8d050e
--- /dev/null
+++ b/arch/c6x/lib/csum_64plus.S
@@ -0,0 +1,408 @@
+;
+; linux/arch/c6x/lib/csum_64plus.s
+;
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot ([email protected])
+;
+; 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.
+;
+
+;
+;unsigned int csum_partial_copy(const char *src, char * dst,
+; int len, int sum)
+;
+; A4: src
+; B4: dst
+; A6: len
+; B6: sum
+; return csum in A4
+;
+
+ .global csum_partial_copy
+ .text
+
+csum_partial_copy:
+ MVC .S2 ILC,B30
+
+ MV .D1X B6,A31 ; given csum
+ ZERO .D1 A9 ; csum (a side)
+|| ZERO .D2 B9 ; csum (b side)
+|| SHRU .S2X A6,2,B5 ; len / 4
+
+ ;; Check alignment and size
+ AND .S1 3,A4,A1
+|| AND .S2 3,B4,B0
+ OR .L2X B0,A1,B0 ; non aligned condition
+|| MVC .S2 B5,ILC
+|| MVK .D2 1,B2
+|| MV .D1X B5,A1 ; words condition
+ [!A1] B .S1 L8
+ [B0] BNOP .S1 L6,5
+
+ SPLOOP 1
+
+ ;; Main loop for aligned words
+ LDW .D1T1 *A4++,A7
+ NOP 4
+ MV .S2X A7,B7
+|| EXTU .S1 A7,0,16,A16
+ STW .D2T2 B7,*B4++
+|| MPYU .M2 B7,B2,B8
+|| ADD .L1 A16,A9,A9
+ NOP
+ SPKERNEL 8,0
+|| ADD .L2 B8,B9,B9
+
+ ZERO .D1 A1
+|| ADD .L1X A9,B9,A9 ; add csum from a and b sides
+
+L6:
+ [!A1] BNOP .S1 L8,5
+
+ ;; Main loop for non-aligned words
+ SPLOOP 2
+ || MVK .L1 1,A2
+
+ LDNW .D1T1 *A4++,A7
+ NOP 3
+
+ NOP
+ MV .S2X A7,B7
+ || EXTU .S1 A7,0,16,A16
+ || MPYU .M1 A7,A2,A8
+
+ ADD .L1 A16,A9,A9
+ SPKERNEL 6,0
+ || STNW .D2T2 B7,*B4++
+ || ADD .L1 A8,A9,A9
+
+L8: AND .S2X 2,A6,B5
+ CMPGT .L2 B5,0,B0
+ [!B0] BNOP .S1 L82,4
+
+ ;; Manage half-word
+ ZERO .L1 A7
+|| ZERO .D1 A8
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+
+ LDBU .D1T1 *A4++,A7
+ LDBU .D1T1 *A4++,A8
+ NOP 3
+ SHL .S1 A7,8,A0
+ ADD .S1 A8,A9,A9
+ STB .D2T1 A7,*B4++
+|| ADD .S1 A0,A9,A9
+ STB .D2T1 A8,*B4++
+
+#else
+
+ LDBU .D1T1 *A4++,A7
+ LDBU .D1T1 *A4++,A8
+ NOP 3
+ ADD .S1 A7,A9,A9
+ SHL .S1 A8,8,A0
+
+ STB .D2T1 A7,*B4++
+|| ADD .S1 A0,A9,A9
+ STB .D2T1 A8,*B4++
+
+#endif
+
+ ;; Manage eventually the last byte
+L82: AND .S2X 1,A6,B0
+ [!B0] BNOP .S1 L9,5
+
+|| ZERO .L1 A7
+
+L83: LDBU .D1T1 *A4++,A7
+ NOP 4
+
+ MV .L2X A7,B7
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+
+ STB .D2T2 B7,*B4++
+|| SHL .S1 A7,8,A7
+ ADD .S1 A7,A9,A9
+
+#else
+
+ STB .D2T2 B7,*B4++
+|| ADD .S1 A7,A9,A9
+
+#endif
+
+ ;; Fold the csum
+L9: SHRU .S2X A9,16,B0
+ [!B0] BNOP .S1 L10,5
+
+L91: SHRU .S2X A9,16,B4
+|| EXTU .S1 A9,16,16,A3
+ ADD .D1X A3,B4,A9
+
+ SHRU .S1 A9,16,A0
+ [A0] BNOP .S1 L91,5
+
+L10: ADD .D1 A31,A9,A9
+ MV .D1 A9,A4
+
+ BNOP .S2 B3,4
+ MVC .S2 B30,ILC
+
+ .global csum_partial_copy_old
+ .text
+
+;
+;unsigned short
+;ip_fast_csum(unsigned char *iph, unsigned int ihl)
+;{
+; unsigned int checksum = 0;
+; unsigned short *tosum = (unsigned short *) iph;
+; int len;
+;
+; len = ihl*4;
+;
+; if (len <= 0)
+; return 0;
+;
+; while(len) {
+; len -= 2;
+; checksum += *tosum++;
+; }
+; if (len & 1)
+; checksum += *(unsigned char*) tosum;
+;
+; while(checksum >> 16)
+; checksum = (checksum & 0xffff) + (checksum >> 16);
+;
+; return ~checksum;
+;}
+;
+; A4: iph
+; B4: ihl
+; return checksum in A4
+;
+
+ .global ip_fast_csum
+ .text
+
+ip_fast_csum:
+ ZERO .D1 A5
+ || MVC .S2 ILC,B30
+ SHL .S2 B4,2,B0
+ CMPGT .L2 B0,0,B1
+ [!B1] BNOP .S1 L15,4
+ [!B1] ZERO .D1 A3
+
+ [!B0] B .S1 L12
+ SHRU .S2 B0,1,B0
+ MVC .S2 B0,ILC
+ NOP 3
+
+ SPLOOP 1
+ LDHU .D1T1 *A4++,A3
+ NOP 3
+ NOP
+ SPKERNEL 5,0
+ || ADD .L1 A3,A5,A5
+
+L12: SHRU .S1 A5,16,A0
+ [!A0] BNOP .S1 L14,5
+
+L13: SHRU .S2X A5,16,B4
+ EXTU .S1 A5,16,16,A3
+ ADD .D1X A3,B4,A5
+ SHRU .S1 A5,16,A0
+ [A0] BNOP .S1 L13,5
+
+L14: NOT .D1 A5,A3
+ EXTU .S1 A3,16,16,A3
+
+L15: BNOP .S2 B3,3
+ MVC .S2 B30,ILC
+ MV .D1 A3,A4
+
+;
+;unsigned short
+;do_csum(unsigned char *buff, unsigned int len)
+;{
+; int odd, count;
+; unsigned int result = 0;
+;
+; if (len <= 0)
+; goto out;
+; odd = 1 & (unsigned long) buff;
+; if (odd) {
+;#ifdef __LITTLE_ENDIAN
+; result += (*buff << 8);
+;#else
+; result = *buff;
+;#endif
+; 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) {
+; unsigned int carry = 0;
+; do {
+; unsigned int w = *(unsigned int *) buff;
+; count--;
+; buff += 4;
+; result += carry;
+; result += w;
+; carry = (w > result);
+; } while (count);
+; result += carry;
+; result = (result & 0xffff) + (result >> 16);
+; }
+; if (len & 2) {
+; result += *(unsigned short *) buff;
+; buff += 2;
+; }
+; }
+; if (len & 1)
+;#ifdef __LITTLE_ENDIAN
+; result += *buff;
+;#else
+; result += (*buff << 8);
+;#endif
+; result = (result & 0xffff) + (result >> 16);
+; /* add up carry.. */
+; result = (result & 0xffff) + (result >> 16);
+; if (odd)
+; result = ((result >> 8) & 0xff) | ((result & 0xff) << 8);
+;out:
+; return result;
+;}
+;
+; A4: buff
+; B4: len
+; return checksum in A4
+;
+ .global do_csum
+ .text
+do_csum:
+ CMPGT .L2 B4,0,B0
+ [!B0] BNOP .S1 L26,3
+ EXTU .S1 A4,31,31,A0
+
+ MV .L1 A0,A3
+|| MV .S1X B3,A5
+|| MV .L2 B4,B3
+|| ZERO .D1 A1
+
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ [A0] SUB .L2 B3,1,B3
+|| [A0] LDBU .D1T1 *A4++,A1
+#else
+ [!A0] BNOP .S1 L21,5
+|| [A0] LDBU .D1T1 *A4++,A0
+ SUB .L2 B3,1,B3
+|| SHL .S1 A0,8,A1
+L21:
+#endif
+ SHR .S2 B3,1,B0
+ [!B0] BNOP .S1 L24,3
+ MVK .L1 2,A0
+ AND .L1 A4,A0,A0
+
+ [!A0] BNOP .S1 L22,5
+|| [A0] LDHU .D1T1 *A4++,A0
+ SUB .L2 B0,1,B0
+|| SUB .S2 B3,2,B3
+|| ADD .L1 A0,A1,A1
+L22:
+ SHR .S2 B0,1,B0
+|| ZERO .L1 A0
+
+ [!B0] BNOP .S1 L23,5
+|| [B0] MVC .S2 B0,ILC
+
+ SPLOOP 3
+ SPMASK L1
+|| MV .L1 A1,A2
+|| LDW .D1T1 *A4++,A1
+
+ NOP 4
+ ADD .L1 A0,A1,A0
+ ADD .L1 A2,A0,A2
+
+ SPKERNEL 1,2
+|| CMPGTU .L1 A1,A2,A0
+
+ ADD .L1 A0,A2,A6
+ EXTU .S1 A6,16,16,A7
+ SHRU .S2X A6,16,B0
+ NOP 1
+ ADD .L1X A7,B0,A1
+L23:
+ MVK .L2 2,B0
+ AND .L2 B3,B0,B0
+ [B0] LDHU .D1T1 *A4++,A0
+ NOP 4
+ [B0] ADD .L1 A0,A1,A1
+L24:
+ EXTU .S2 B3,31,31,B0
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ [!B0] BNOP .S1 L25,4
+|| [B0] LDBU .D1T1 *A4,A0
+ SHL .S1 A0,8,A0
+ ADD .L1 A0,A1,A1
+L25:
+#else
+ [B0] LDBU .D1T1 *A4,A0
+ NOP 4
+ [B0] ADD .L1 A0,A1,A1
+#endif
+ EXTU .S1 A1,16,16,A0
+ SHRU .S2X A1,16,B0
+ NOP 1
+ ADD .L1X A0,B0,A0
+ SHRU .S1 A0,16,A1
+ ADD .L1 A0,A1,A0
+ EXTU .S1 A0,16,16,A1
+ EXTU .S1 A1,16,24,A2
+
+ EXTU .S1 A1,24,16,A0
+|| MV .L2X A3,B0
+
+ [B0] OR .L1 A0,A2,A1
+L26:
+ NOP 1
+ BNOP .S2X A5,4
+ MV .L1 A1,A4
+
+;__wsum csum_partial(const void *buff, int len, __wsum wsum)
+;{
+; unsigned int sum = (__force unsigned int)wsum;
+; unsigned int result = do_csum(buff, len);
+;
+; /* add in old sum, and carry.. */
+; result += sum;
+; if (sum > result)
+; result += 1;
+; return (__force __wsum)result;
+;}
+;
+ .global csum_partial
+csum_partial:
+ MV .L1X B3,A9
+|| CALLP .S2 do_csum,B3
+|| MV .S1 A6,A8
+ BNOP .S2X A9,2
+ ADD .L1 A8,A4,A1
+ CMPGTU .L1 A8,A1,A0
+ ADD .L1 A1,A0,A4
diff --git a/arch/c6x/lib/divi.S b/arch/c6x/lib/divi.S
new file mode 100644
index 0000000..8613f18
--- /dev/null
+++ b/arch/c6x/lib/divi.S
@@ -0,0 +1,51 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+ .text
+ .global __c6xabi_divi
+__c6xabi_divi:
+ call .s2 __c6xabi_divu
+|| mv .d2 B3, B5
+|| cmpgt .l1 0, A4, A1
+|| cmpgt .l2 0, B4, B1
+
+ [A1] neg .l1 A4, A4
+|| [B1] neg .l2 B4, B4
+|| xor .s1x A1, B1, A1
+ [A1] addkpc .s2 _divu_ret, B3, 4
+_divu_ret:
+ neg .l1 A4, A4
+|| mv .l2 B3,B5
+|| ret .s2 B5
+ nop 5
diff --git a/arch/c6x/lib/divremi.S b/arch/c6x/lib/divremi.S
new file mode 100644
index 0000000..d0ed842
--- /dev/null
+++ b/arch/c6x/lib/divremi.S
@@ -0,0 +1,45 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ .text
+ .global __c6xabi_divremi
+
+__c6xabi_divremi:
+ stw .d2t2 B3, *B15--[2]
+|| cmpgt .l1 0, A4, A1
+|| cmpgt .l2 0, B4, B2
+|| mv .s1 A4, A5
+|| call .s2 __c6xabi_divu
+
+ [A1] neg .l1 A4, A4
+|| [B2] neg .l2 B4, B4
+|| xor .s2x B2, A1, B0
+|| mv .d2 B4, B2
+
+ [B0] addkpc .s2 _divu_ret_1, B3, 1
+ [!B0] addkpc .s2 _divu_ret_2, B3, 1
+ nop 2
+_divu_ret_1:
+ neg .l1 A4, A4
+_divu_ret_2:
+ ldw .d2t2 *++B15[2], B3
+
+ mpy32 .m1x A4, B2, A6
+ nop 3
+ ret .s2 B3
+ sub .l1 A5, A6, A5
+ nop 4
diff --git a/arch/c6x/lib/divremu.S b/arch/c6x/lib/divremu.S
new file mode 100644
index 0000000..32adbe5
--- /dev/null
+++ b/arch/c6x/lib/divremu.S
@@ -0,0 +1,86 @@
+;; Copyright 2011 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ .text
+ .global __c6xabi_divremu
+
+__c6xabi_divremu:
+ ;; We use a series of up to 31 subc instructions. First, we find
+ ;; out how many leading zero bits there are in the divisor. This
+ ;; gives us both a shift count for aligning (shifting) the divisor
+ ;; to the, and the number of times we have to execute subc.
+
+ ;; At the end, we have both the remainder and most of the quotient
+ ;; in A4. The top bit of the quotient is computed first and is
+ ;; placed in A2.
+
+ ;; Return immediately if the dividend is zero. Setting B4 to 1
+ ;; is a trick to allow us to leave the following insns in the jump
+ ;; delay slot without affecting the result.
+ mv .s2x A4, B1
+
+ [b1] lmbd .l2 1, B4, B1
+||[!b1] b .s2 B3 ; RETURN A
+||[!b1] mvk .d2 1, B4
+
+||[!b1] zero .s1 A5
+ mv .l1x B1, A6
+|| shl .s2 B4, B1, B4
+
+ ;; The loop performs a maximum of 28 steps, so we do the
+ ;; first 3 here.
+ cmpltu .l1x A4, B4, A2
+ [!A2] sub .l1x A4, B4, A4
+|| shru .s2 B4, 1, B4
+|| xor .s1 1, A2, A2
+
+ shl .s1 A2, 31, A2
+|| [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+
+ ;; RETURN A may happen here (note: must happen before the next branch)
+__divremu0:
+ cmpgt .l2 B1, 7, B0
+|| [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+|| [b0] b .s1 __divremu0
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ [b1] subc .l1x A4,B4,A4
+|| [b1] add .s2 -1, B1, B1
+ ;; loop backwards branch happens here
+
+ ret .s2 B3
+|| mvk .s1 32, A1
+ sub .l1 A1, A6, A6
+|| extu .s1 A4, A6, A5
+ shl .s1 A4, A6, A4
+ shru .s1 A4, 1, A4
+|| sub .l1 A6, 1, A6
+ or .l1 A2, A4, A4
+ shru .s1 A4, A6, A4
+ nop
diff --git a/arch/c6x/lib/divu.S b/arch/c6x/lib/divu.S
new file mode 100644
index 0000000..54e147f
--- /dev/null
+++ b/arch/c6x/lib/divu.S
@@ -0,0 +1,97 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+ .text
+ .global __c6xabi_divu
+__c6xabi_divu:
+ ;; We use a series of up to 31 subc instructions. First, we find
+ ;; out how many leading zero bits there are in the divisor. This
+ ;; gives us both a shift count for aligning (shifting) the divisor
+ ;; to the, and the number of times we have to execute subc.
+
+ ;; At the end, we have both the remainder and most of the quotient
+ ;; in A4. The top bit of the quotient is computed first and is
+ ;; placed in A2.
+
+ ;; Return immediately if the dividend is zero.
+ mv .s2x A4, B1
+ [B1] lmbd .l2 1, B4, B1
+|| [!B1] b .s2 B3 ; RETURN A
+|| [!B1] mvk .d2 1, B4
+ mv .l1x B1, A6
+|| shl .s2 B4, B1, B4
+
+ ;; The loop performs a maximum of 28 steps, so we do the
+ ;; first 3 here.
+ cmpltu .l1x A4, B4, A2
+ [!A2] sub .l1x A4, B4, A4
+|| shru .s2 B4, 1, B4
+|| xor .s1 1, A2, A2
+
+ shl .s1 A2, 31, A2
+|| [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+
+ ;; RETURN A may happen here (note: must happen before the next branch)
+_divu_loop:
+ cmpgt .l2 B1, 7, B0
+|| [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+|| [B0] b .s1 _divu_loop
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ ;; loop backwards branch happens here
+
+ ret .s2 B3
+|| mvk .s1 32, A1
+ sub .l1 A1, A6, A6
+ shl .s1 A4, A6, A4
+ shru .s1 A4, 1, A4
+|| sub .l1 A6, 1, A6
+ or .l1 A2, A4, A4
+ shru .s1 A4, A6, A4
+ nop
+
diff --git a/arch/c6x/lib/divull.c b/arch/c6x/lib/divull.c
new file mode 100644
index 0000000..97eae9b
--- /dev/null
+++ b/arch/c6x/lib/divull.c
@@ -0,0 +1,332 @@
+/* Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
+ 2000, 2001, 2002 Free Software Foundation, Inc.
+
+This code was pulled from an old (GPLv2) libgcc.
+
+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, or (at your option) any later version.
+
+In addition to the permissions in the GNU General Public License, the
+Free Software Foundation gives you unlimited permission to link the
+compiled version of this file into combinations with other programs,
+and to distribute those combinations without any restriction coming
+from the use of this file. (The General Public License restrictions
+do apply in other respects; for example, they cover modification of
+the file, and distribution when not linked into a combine
+executable.)
+
+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 GCC; see the file COPYING. If not, write to the Free
+Software Foundation, 59 Temple Place - Suite 330, Boston, MA
+02111-1307, USA. */
+
+#include <linux/types.h>
+#include <linux/bitops.h>
+
+static inline unsigned __clz(unsigned x)
+{
+ asm(" lmbd .l1 1,%0,%0\n" : "+a"(x));
+ return x;
+}
+#define count_leading_zeros(count, x) (count) = __clz(x)
+
+#define W_TYPE_SIZE 32
+
+#define __BITS4 (W_TYPE_SIZE / 4)
+#define __ll_B ((uint32_t) 1 << (W_TYPE_SIZE / 2))
+#define __ll_lowpart(t) ((uint32_t) (t) & (__ll_B - 1))
+#define __ll_highpart(t) ((uint32_t) (t) >> (W_TYPE_SIZE / 2))
+
+
+#define sub_ddmmss(sh, sl, ah, al, bh, bl) \
+ do { \
+ uint32_t __x; \
+ __x = (al) - (bl); \
+ (sh) = (ah) - (bh) - (__x > (al)); \
+ (sl) = __x; \
+ } while (0)
+
+#define umul_ppmm(w1, w0, u, v) \
+ do { \
+ uint32_t __x0, __x1, __x2, __x3; \
+ uint16_t __ul, __vl, __uh, __vh; \
+ \
+ __ul = __ll_lowpart(u); \
+ __uh = __ll_highpart(u); \
+ __vl = __ll_lowpart(v); \
+ __vh = __ll_highpart(v); \
+ \
+ __x0 = (uint32_t) __ul * __vl; \
+ __x1 = (uint32_t) __ul * __vh; \
+ __x2 = (uint32_t) __uh * __vl; \
+ __x3 = (uint32_t) __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 __udiv_qrnnd_c(q, r, n1, n0, d) \
+ do { \
+ uint32_t __d1, __d0, __q1, __q0; \
+ uint32_t __r1, __r0, __m; \
+ __d1 = __ll_highpart(d); \
+ __d0 = __ll_lowpart(d); \
+ \
+ __r1 = (n1) % __d1; \
+ __q1 = (n1) / __d1; \
+ __m = (uint32_t) __q1 * __d0; \
+ __r1 = __r1 * __ll_B | __ll_highpart(n0); \
+ if (__r1 < __m) { \
+ __q1--, __r1 += (d); \
+ /* i.e. we didn't get carry when adding to __r1 */ \
+ if (__r1 >= (d)) \
+ if (__r1 < __m) \
+ __q1--, __r1 += (d); \
+ } \
+ __r1 -= __m; \
+ \
+ __r0 = __r1 % __d1; \
+ __q0 = __r1 / __d1; \
+ __m = (uint32_t) __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) = (uint32_t) __q1 * __ll_B | __q0; \
+ (r) = __r0; \
+ } while (0)
+
+#define UDIV_NEEDS_NORMALIZATION 1
+#define udiv_qrnnd __udiv_qrnnd_c
+
+struct llstruct {
+#ifdef CONFIG_CPU_BIG_ENDIAN
+ uint32_t high;
+ uint32_t low;
+#else
+ uint32_t low;
+ uint32_t high;
+#endif
+};
+
+typedef union {
+ struct llstruct s;
+ int64_t ll;
+} llunion_t;
+
+static inline uint64_t __udivmoddi4(uint64_t n, uint64_t d, uint64_t *rp)
+{
+ llunion_t ww;
+ llunion_t nn, dd;
+ llunion_t rr;
+ uint32_t d0, d1, n0, n1, n2;
+ uint32_t q0, q1;
+ uint32_t b, bm;
+
+ nn.ll = n;
+ dd.ll = d;
+
+ 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 != NULL) {
+ 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 != NULL) {
+ 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 != NULL) {
+ rr.s.low = n0;
+ rr.s.high = n1;
+ *rp = rr.ll;
+ }
+ } else {
+ uint32_t 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 != NULL) {
+ 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;
+}
+
+uint64_t
+__c6xabi_divull(uint64_t n, uint64_t d)
+{
+ return __udivmoddi4(n, d, (uint64_t *)0);
+}
+
diff --git a/arch/c6x/lib/llshl.S b/arch/c6x/lib/llshl.S
new file mode 100644
index 0000000..99b739e
--- /dev/null
+++ b/arch/c6x/lib/llshl.S
@@ -0,0 +1,36 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <[email protected]>.
+;;
+;; 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.
+
+;; uint64_t __c6xabi_llshl(uint64_t val, uint shift)
+
+ .text
+ .global __c6xabi_llshl
+__c6xabi_llshl:
+ mv .l1x B4,A1
+ [!A1] b .s2 B3 ; just return if zero shift
+ mvk .s1 32,A0
+ sub .d1 A0,A1,A0
+ cmplt .l1 0,A0,A2
+ [A2] shru .s1 A4,A0,A0
+ [!A2] neg .l1 A0,A5
+|| [A2] shl .s1 A5,A1,A5
+ [!A2] shl .s1 A4,A5,A5
+|| [A2] or .d1 A5,A0,A5
+|| [!A2] mvk .l1 0,A4
+ [A2] shl .s1 A4,A1,A4
+ bnop .s2 B3,5
+
diff --git a/arch/c6x/lib/llshr.S b/arch/c6x/lib/llshr.S
new file mode 100644
index 0000000..989feed
--- /dev/null
+++ b/arch/c6x/lib/llshr.S
@@ -0,0 +1,36 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <[email protected]>.
+;;
+;; 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.
+
+;; uint64_t __c6xabi_llshr(uint64_t val, uint shift)
+
+ .text
+ .global __c6xabi_llshr
+__c6xabi_llshr:
+ mv .l1x B4,A1
+ [!A1] b .s2 B3 ; return if zero shift count
+ mvk .s1 32,A0
+ sub .d1 A0,A1,A0
+ cmplt .l1 0,A0,A2
+ [A2] shl .s1 A5,A0,A0
+ nop
+ [!A2] neg .l1 A0,A4
+|| [A2] shru .s1 A4,A1,A4
+ [!A2] shr .s1 A5,A4,A4
+|| [A2] or .d1 A4,A0,A4
+ [!A2] shr .s1 A5,0x1f,A5
+ [A2] shr .s1 A5,A1,A5
+ bnop .s2 B3,5
diff --git a/arch/c6x/lib/llshru.S b/arch/c6x/lib/llshru.S
new file mode 100644
index 0000000..07a4631
--- /dev/null
+++ b/arch/c6x/lib/llshru.S
@@ -0,0 +1,36 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <[email protected]>.
+;;
+;; 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.
+
+;; uint64_t __c6xabi_llshru(uint64_t val, uint shift)
+
+ .text
+ .global __c6xabi_llshru
+__c6xabi_llshru:
+ mv .l1x B4,A1
+ [!A1] b .s2 B3 ; return if zero shift count
+ mvk .s1 32,A0
+ sub .d1 A0,A1,A0
+ cmplt .l1 0,A0,A2
+ [A2] shl .s1 A5,A0,A0
+ nop
+ [!A2] neg .l1 A0,A4
+|| [A2] shru .s1 A4,A1,A4
+ [!A2] shru .s1 A5,A4,A4
+|| [A2] or .d1 A4,A0,A4
+|| [!A2] mvk .l1 0,A5
+ [A2] shru .s1 A5,A1,A5
+ bnop .s2 B3,5
diff --git a/arch/c6x/lib/memcmp.c b/arch/c6x/lib/memcmp.c
new file mode 100644
index 0000000..2393530
--- /dev/null
+++ b/arch/c6x/lib/memcmp.c
@@ -0,0 +1,26 @@
+/*
+ * linux/arch/c6x/lib/memcmp.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/module.h>
+
+int memcmp(const void *cs, const void *ct, size_t count)
+{
+ const unsigned char *su1, *su2;
+
+ for (su1 = cs, su2 = ct; 0 < count; ++su1, ++su2, count--)
+ if (*su1 != *su2)
+ return (*su1 < *su2) ? -1 : 1;
+ return 0;
+}
+EXPORT_SYMBOL(memcmp);
+
diff --git a/arch/c6x/lib/memcpy_64plus.S b/arch/c6x/lib/memcpy_64plus.S
new file mode 100644
index 0000000..231ee25
--- /dev/null
+++ b/arch/c6x/lib/memcpy_64plus.S
@@ -0,0 +1,45 @@
+; Port on Texas Instruments TMS320C6x architecture
+;
+; Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+; Author: Aurelien Jacquiot ([email protected])
+;
+; 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.
+;
+
+ .global memcpy
+ .text
+
+memcpy:
+ AND .L1 0x1,A6,A0
+ || AND .S1 0x2,A6,A1
+ || AND .L2X 0x4,A6,B0
+ || MV .D1 A4,A3
+ || MVC .S2 ILC,B2
+
+ [A0] LDB .D2T1 *B4++,A5
+ [A1] LDB .D2T1 *B4++,A7
+ [A1] LDB .D2T1 *B4++,A8
+ [B0] LDNW .D2T1 *B4++,A9
+ || SHRU .S2X A6,0x3,B1
+ [!B1] BNOP .S2 B3,1
+
+ [A0] STB .D1T1 A5,*A3++
+ ||[B1] MVC .S2 B1,ILC
+ [A1] STB .D1T1 A7,*A3++
+ [A1] STB .D1T1 A8,*A3++
+ [B0] STNW .D1T1 A9,*A3++ ; return when len < 8
+
+ SPLOOP 2
+
+ LDNDW .D2T1 *B4++,A9:A8
+ NOP 3
+
+ NOP
+ SPKERNEL 0,0
+ || STNDW .D1T1 A9:A8,*A3++
+
+ BNOP .S2 B3,4
+ MVC .S2 B2,ILC
+
diff --git a/arch/c6x/lib/memmove.c b/arch/c6x/lib/memmove.c
new file mode 100644
index 0000000..23b6a81
--- /dev/null
+++ b/arch/c6x/lib/memmove.c
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/c6x/lib/memmove.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2005, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/string.h>
+
+void *memmove(void *s1, const void *s2, size_t n)
+{
+ register char *s = (char *) s1;
+ register const char *p = (const char *) s2;
+
+ if (p >= s) {
+ return memcpy(s, p, n);
+ } else {
+ while (n) {
+ --n;
+ s[n] = p[n];
+ }
+ }
+ return s1;
+}
+EXPORT_SYMBOL(memmove);
diff --git a/arch/c6x/lib/memset.c b/arch/c6x/lib/memset.c
new file mode 100644
index 0000000..7fda20f
--- /dev/null
+++ b/arch/c6x/lib/memset.c
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/c6x/lib/memcmp.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2004, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/module.h>
+
+void *memset(void *mem, register int ch, register size_t length)
+{
+ register char *m = (char *)mem - 1;
+
+ while (length--)
+ *++m = ch;
+ return mem;
+}
+EXPORT_SYMBOL(memset);
+
diff --git a/arch/c6x/lib/mpyll.S b/arch/c6x/lib/mpyll.S
new file mode 100644
index 0000000..d2427ab
--- /dev/null
+++ b/arch/c6x/lib/mpyll.S
@@ -0,0 +1,47 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <[email protected]>.
+;;
+;; 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.
+
+ ;; uint64_t __c6xabi_mpyll(uint64_t x, uint64_t y)
+ ;;
+ ;; 64x64 multiply
+ ;; First compute partial results using 32-bit parts of x and y:
+ ;;
+ ;; b63 b32 b31 b0
+ ;; -----------------------------
+ ;; | 1 | 0 |
+ ;; -----------------------------
+ ;;
+ ;; P0 = X0*Y0
+ ;; P1 = X0*Y1 + X1*Y0
+ ;; P2 = X1*Y1
+ ;;
+ ;; result = (P2 << 64) + (P1 << 32) + P0
+ ;;
+ ;; Since the result is also 64-bit, we can skip the P2 term.
+
+ .text
+ .global __c6xabi_mpyll
+__c6xabi_mpyll:
+ mpy32u .m1x A4,B4,A1:A0 ; X0*Y0
+ b .s2 B3
+ || mpy32u .m2x B5,A4,B1:B0 ; X0*Y1 (don't need upper 32-bits)
+ || mpy32u .m1x A5,B4,A3:A2 ; X1*Y0 (don't need upper 32-bits)
+ nop
+ nop
+ mv .s1 A0,A4
+ add .l1x A2,B0,A5
+ add .s1 A1,A5,A5
diff --git a/arch/c6x/lib/negll.S b/arch/c6x/lib/negll.S
new file mode 100644
index 0000000..7747521
--- /dev/null
+++ b/arch/c6x/lib/negll.S
@@ -0,0 +1,29 @@
+;; Copyright (C) 2010 Texas Instruments Incorporated
+;; Contributed by Mark Salter <[email protected]>.
+;;
+;; 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.
+
+;; int64_t __c6xabi_negll(int64_t val)
+
+ .text
+ .global __c6xabi_negll
+__c6xabi_negll:
+ b .s2 B3
+ mvk .l1 0,A0
+ subu .l1 A0,A4,A3:A2
+ sub .l1 A0,A5,A0
+|| ext .s1 A3,24,24,A5
+ add .l1 A5,A0,A5
+ mv .s1 A2,A4
diff --git a/arch/c6x/lib/pop_rts.S b/arch/c6x/lib/pop_rts.S
new file mode 100644
index 0000000..e1847fb
--- /dev/null
+++ b/arch/c6x/lib/pop_rts.S
@@ -0,0 +1,30 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ .text
+ .global __c6xabi_pop_rts
+
+__c6xabi_pop_rts:
+ lddw .d2t2 *++B15, B3:B2
+ lddw .d2t1 *++B15, A11:A10
+ lddw .d2t2 *++B15, B11:B10
+ lddw .d2t1 *++B15, A13:A12
+ lddw .d2t2 *++B15, B13:B12
+ lddw .d2t1 *++B15, A15:A14
+|| b .s2 B3
+ ldw .d2t2 *++B15[2], B14
+ nop 4
diff --git a/arch/c6x/lib/push_rts.S b/arch/c6x/lib/push_rts.S
new file mode 100644
index 0000000..637d56a
--- /dev/null
+++ b/arch/c6x/lib/push_rts.S
@@ -0,0 +1,28 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ .text
+ .global __c6xabi_push_rts
+__c6xabi_push_rts:
+ stw .d2t2 B14, *B15--[2]
+ stdw .d2t1 A15:A14, *B15--
+|| b .s2x A3
+ stdw .d2t2 B13:B12, *B15--
+ stdw .d2t1 A13:A12, *B15--
+ stdw .d2t2 B11:B10, *B15--
+ stdw .d2t1 A11:A10, *B15--
+ stdw .d2t2 B3:B2, *B15--
diff --git a/arch/c6x/lib/remi.S b/arch/c6x/lib/remi.S
new file mode 100644
index 0000000..cb6063f
--- /dev/null
+++ b/arch/c6x/lib/remi.S
@@ -0,0 +1,62 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+ .text
+ .global __c6xabi_remi
+
+__c6xabi_remi:
+ stw .d2t2 B3, *B15--[2]
+|| cmpgt .l1 0, A4, A1
+|| cmpgt .l2 0, B4, B2
+|| mv .s1 A4, A5
+|| call .s2 __c6xabi_divu
+
+ [A1] neg .l1 A4, A4
+|| [B2] neg .l2 B4, B4
+|| xor .s2x B2, A1, B0
+|| mv .d2 B4, B2
+
+ [B0] addkpc .s2 _divu_ret_1, B3, 1
+ [!B0] addkpc .s2 _divu_ret_2, B3, 1
+ nop 2
+_divu_ret_1:
+ neg .l1 A4, A4
+_divu_ret_2:
+ ldw .d2t2 *++B15[2], B3
+
+ mpy32 .m1x A4, B2, A6
+ nop 3
+ ret .s2 B3
+ sub .l1 A5, A6, A4
+ nop 4
diff --git a/arch/c6x/lib/remu.S b/arch/c6x/lib/remu.S
new file mode 100644
index 0000000..e1d9f30
--- /dev/null
+++ b/arch/c6x/lib/remu.S
@@ -0,0 +1,81 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ ;; ABI considerations for the divide functions
+ ;; The following registers are call-used:
+ ;; __c6xabi_divi A0,A1,A2,A4,A6,B0,B1,B2,B4,B5
+ ;; __c6xabi_divu A0,A1,A2,A4,A6,B0,B1,B2,B4
+ ;; __c6xabi_remi A1,A2,A4,A5,A6,B0,B1,B2,B4
+ ;; __c6xabi_remu A1,A4,A5,A7,B0,B1,B2,B4
+ ;;
+ ;; In our implementation, divu and remu are leaf functions,
+ ;; while both divi and remi call into divu.
+ ;; A0 is not clobbered by any of the functions.
+ ;; divu does not clobber B2 either, which is taken advantage of
+ ;; in remi.
+ ;; divi uses B5 to hold the original return address during
+ ;; the call to divu.
+ ;; remi uses B2 and A5 to hold the input values during the
+ ;; call to divu. It stores B3 in on the stack.
+
+
+ .text
+ .global __c6xabi_remu
+
+__c6xabi_remu:
+ ;; The ABI seems designed to prevent these functions calling each other,
+ ;; so we duplicate most of the divsi3 code here.
+ mv .s2x A4, B1
+ lmbd .l2 1, B4, B1
+|| [!B1] b .s2 B3 ; RETURN A
+|| [!B1] mvk .d2 1, B4
+
+ mv .l1x B1, A7
+|| shl .s2 B4, B1, B4
+
+ cmpltu .l1x A4, B4, A1
+ [!A1] sub .l1x A4, B4, A4
+ shru .s2 B4, 1, B4
+
+_remu_loop:
+ cmpgt .l2 B1, 7, B0
+|| [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ ;; RETURN A may happen here (note: must happen before the next branch)
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+|| [B0] b .s1 _remu_loop
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ ;; loop backwards branch happens here
+
+ ret .s2 B3
+ [B1] subc .l1x A4,B4,A4
+|| [B1] add .s2 -1, B1, B1
+ [B1] subc .l1x A4,B4,A4
+
+ extu .s1 A4, A7, A4
+ nop 2
+
diff --git a/arch/c6x/lib/strasgi.S b/arch/c6x/lib/strasgi.S
new file mode 100644
index 0000000..6861e25
--- /dev/null
+++ b/arch/c6x/lib/strasgi.S
@@ -0,0 +1,88 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ .text
+ .global __c6xabi_strasgi
+
+__c6xabi_strasgi:
+
+ ;; This is essentially memcpy, with alignment known to be at least
+ ;; 4, and the size a multiple of 4 greater than or equal to 28.
+ ldw .d2t1 *B4++, A0
+|| mvk .s2 16, B1
+ ldw .d2t1 *B4++, A1
+|| mvk .s2 20, B2
+|| sub .d1 A6, 24, A6
+ ldw .d2t1 *B4++, A5
+ ldw .d2t1 *B4++, A7
+|| mv .l2x A6, B7
+ ldw .d2t1 *B4++, A8
+ ldw .d2t1 *B4++, A9
+|| mv .s2x A0, B5
+|| cmpltu .l2 B2, B7, B0
+
+_strasgi_loop:
+ stw .d1t2 B5, *A4++
+|| [B0] ldw .d2t1 *B4++, A0
+|| mv .s2x A1, B5
+|| mv .l2 B7, B6
+
+ [B0] sub .d2 B6, 24, B7
+|| [B0] b .s2 _strasgi_loop
+|| cmpltu .l2 B1, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A1
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A5, B5
+|| cmpltu .l2 12, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A5
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A7, B5
+|| cmpltu .l2 8, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A7
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A8, B5
+|| cmpltu .l2 4, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A8
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A9, B5
+|| cmpltu .l2 0, B6, B0
+
+ [B0] ldw .d2t1 *B4++, A9
+|| stw .d1t2 B5, *A4++
+|| mv .s2x A0, B5
+|| cmpltu .l2 B2, B7, B0
+
+ ;; loop back branch happens here
+
+ cmpltu .l2 B1, B6, B0
+|| ret .s2 b3
+
+ [B0] stw .d1t1 A1, *A4++
+|| cmpltu .l2 12, B6, B0
+ [B0] stw .d1t1 A5, *A4++
+|| cmpltu .l2 8, B6, B0
+ [B0] stw .d1t1 A7, *A4++
+|| cmpltu .l2 4, B6, B0
+ [B0] stw .d1t1 A8, *A4++
+|| cmpltu .l2 0, B6, B0
+ [B0] stw .d1t1 A9, *A4++
+
+ ;; return happens here
diff --git a/arch/c6x/lib/strasgi_64plus.S b/arch/c6x/lib/strasgi_64plus.S
new file mode 100644
index 0000000..cbeab22
--- /dev/null
+++ b/arch/c6x/lib/strasgi_64plus.S
@@ -0,0 +1,37 @@
+;; Copyright 2010 Free Software Foundation, Inc.
+;; Contributed by Bernd Schmidt <[email protected]>.
+;;
+;; 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.
+
+ .text
+ .global __c6xabi_strasgi_64plus
+
+__c6xabi_strasgi_64plus:
+ shru .s2x a6, 2, b31
+|| mv .s1 a4, a30
+|| mv .d2 b4, b30
+
+ add .s2 -4, b31, b31
+
+ sploopd 1
+|| mvc .s2 b31, ilc
+ ldw .d2t2 *b30++, b31
+ nop 4
+ mv .s1x b31,a31
+ spkernel 6, 0
+|| stw .d1t1 a31, *a30++
+
+ ret .s2 b3
+ nop 5
--
1.6.2.5

2011-05-11 21:07:24

by Mark Salter

[permalink] [raw]
Subject: [PATCH 12/16] C6X: add platform files

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/platforms/Kconfig | 63 ++
arch/c6x/platforms/Makefile | 16 +
arch/c6x/platforms/board-dsk6455.c | 227 +++++++
arch/c6x/platforms/board-evm6457.c | 101 +++
arch/c6x/platforms/board-evm6472.c | 144 ++++
arch/c6x/platforms/board-evm6474.c | 112 ++++
arch/c6x/platforms/board-evm6474lite.c | 110 ++++
arch/c6x/platforms/include/mach/board-dsk6455.h | 53 ++
arch/c6x/platforms/include/mach/board-evm6457.h | 25 +
arch/c6x/platforms/include/mach/board-evm6472.h | 23 +
arch/c6x/platforms/include/mach/board-evm6474.h | 23 +
arch/c6x/platforms/include/mach/board-evm6474l.h | 23 +
arch/c6x/platforms/include/mach/board.h | 32 +
arch/c6x/platforms/include/mach/cache.h | 104 +++
arch/c6x/platforms/include/mach/dscr.h | 184 ++++++
arch/c6x/platforms/include/mach/emif.h | 63 ++
arch/c6x/platforms/include/mach/gemac.h | 763 ++++++++++++++++++++++
arch/c6x/platforms/include/mach/gmdio.h | 18 +
arch/c6x/platforms/include/mach/hardware.h | 194 ++++++
arch/c6x/platforms/include/mach/irq-c645x.h | 131 ++++
arch/c6x/platforms/include/mach/irq-c6472.h | 138 ++++
arch/c6x/platforms/include/mach/irq-c6474.h | 323 +++++++++
arch/c6x/platforms/include/mach/irq.h | 52 ++
arch/c6x/platforms/include/mach/pll.h | 134 ++++
arch/c6x/platforms/include/mach/timer.h | 104 +++
arch/c6x/platforms/phy.c | 141 ++++
arch/c6x/platforms/platform-c64xx.c | 439 +++++++++++++
arch/c6x/platforms/sgmii.c | 83 +++
28 files changed, 3823 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/platforms/Kconfig
create mode 100644 arch/c6x/platforms/Makefile
create mode 100644 arch/c6x/platforms/board-dsk6455.c
create mode 100644 arch/c6x/platforms/board-evm6457.c
create mode 100644 arch/c6x/platforms/board-evm6472.c
create mode 100644 arch/c6x/platforms/board-evm6474.c
create mode 100644 arch/c6x/platforms/board-evm6474lite.c
create mode 100644 arch/c6x/platforms/include/mach/board-dsk6455.h
create mode 100644 arch/c6x/platforms/include/mach/board-evm6457.h
create mode 100644 arch/c6x/platforms/include/mach/board-evm6472.h
create mode 100644 arch/c6x/platforms/include/mach/board-evm6474.h
create mode 100644 arch/c6x/platforms/include/mach/board-evm6474l.h
create mode 100644 arch/c6x/platforms/include/mach/board.h
create mode 100644 arch/c6x/platforms/include/mach/cache.h
create mode 100644 arch/c6x/platforms/include/mach/dscr.h
create mode 100644 arch/c6x/platforms/include/mach/emif.h
create mode 100644 arch/c6x/platforms/include/mach/gemac.h
create mode 100644 arch/c6x/platforms/include/mach/gmdio.h
create mode 100644 arch/c6x/platforms/include/mach/hardware.h
create mode 100644 arch/c6x/platforms/include/mach/irq-c645x.h
create mode 100644 arch/c6x/platforms/include/mach/irq-c6472.h
create mode 100644 arch/c6x/platforms/include/mach/irq-c6474.h
create mode 100644 arch/c6x/platforms/include/mach/irq.h
create mode 100644 arch/c6x/platforms/include/mach/pll.h
create mode 100644 arch/c6x/platforms/include/mach/timer.h
create mode 100644 arch/c6x/platforms/phy.c
create mode 100644 arch/c6x/platforms/platform-c64xx.c
create mode 100644 arch/c6x/platforms/sgmii.c

diff --git a/arch/c6x/platforms/Kconfig b/arch/c6x/platforms/Kconfig
new file mode 100644
index 0000000..a271f0f
--- /dev/null
+++ b/arch/c6x/platforms/Kconfig
@@ -0,0 +1,63 @@
+
+config SOC_TMS320C6455
+ bool "TMS320C6455"
+ default n
+ select TMS320C64XPLUS
+ select PLL_TCI648X
+ select TIMER_TCI648X
+ select PIC_C64XPLUS
+
+config SOC_TMS320C6457
+ bool "TMS320C6457"
+ default n
+ select TMS320C64XPLUS
+ select PLL_TCI648X
+ select TIMER_TCI648X
+ select PIC_C64XPLUS
+ select SGMII
+
+config SOC_TMS320C6472
+ bool "TMS320C6472"
+ default n
+ select TMS320C64XPLUS
+ select PLL_TCI648X
+ select TIMER_TCI648X
+ select PIC_C64XPLUS
+
+config SOC_TMS320C6474
+ bool "TMS320C6474"
+ default n
+ select TMS320C64XPLUS
+ select PLL_TCI648X
+ select TIMER_TCI648X
+ select PIC_C64XPLUS
+ select SGMII
+
+comment "Board Selection"
+choice
+ prompt "Board"
+ help
+ This option specifies the specific board for which the kernel will be
+ compiled.
+
+config ARCH_BOARD_DSK6455
+ bool "DSK6455"
+ select SOC_TMS320C6455
+
+config ARCH_BOARD_EVM6457
+ bool "EVM6472"
+ select SOC_TMS320C6457
+
+config ARCH_BOARD_EVM6472
+ bool "EVM6472"
+ select SOC_TMS320C6472
+
+config ARCH_BOARD_EVM6474
+ bool "EVM6474"
+ select SOC_TMS320C6474
+
+config ARCH_BOARD_EVM6474L
+ bool "EVM6474L"
+ select SOC_TMS320C6474
+
+endchoice
diff --git a/arch/c6x/platforms/Makefile b/arch/c6x/platforms/Makefile
new file mode 100644
index 0000000..da0f247
--- /dev/null
+++ b/arch/c6x/platforms/Makefile
@@ -0,0 +1,16 @@
+#
+# Makefile for arch/c6x/platforms
+#
+# Copyright 2010, 2011 Texas Instruments Incorporated
+#
+
+obj-$(CONFIG_TMS320C6X) += platform-c64xx.o
+
+obj-$(CONFIG_SGMII) += sgmii.o
+
+# Board objects
+obj-$(CONFIG_ARCH_BOARD_DSK6455) += board-dsk6455.o
+obj-$(CONFIG_ARCH_BOARD_EVM6457) += board-evm6457.o phy.o
+obj-$(CONFIG_ARCH_BOARD_EVM6472) += board-evm6472.o phy.o
+obj-$(CONFIG_ARCH_BOARD_EVM6474) += board-evm6474.o phy.o
+obj-$(CONFIG_ARCH_BOARD_EVM6474L) += board-evm6474lite.o phy.o
diff --git a/arch/c6x/platforms/board-dsk6455.c b/arch/c6x/platforms/board-dsk6455.c
new file mode 100644
index 0000000..03cca20
--- /dev/null
+++ b/arch/c6x/platforms/board-dsk6455.c
@@ -0,0 +1,227 @@
+/*
+ * linux/arch/c6x/platforms/board-dsk6455.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2008, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/delay.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/map.h>
+#include <linux/mtd/partitions.h>
+
+#include <asm/clock.h>
+#include <mach/dscr.h>
+#include <mach/board.h>
+#include <mach/emif.h>
+
+/*
+ * Resources present on the DSK6455 board
+ */
+static struct resource _flash_res = {
+ .name = "Flash",
+ .start = 0xb0000000,
+ .end = 0xbfffffff,
+ .flags = IORESOURCE_MEM,
+};
+static struct resource _cpld_async_res = {
+ .name = "CPLD async",
+ .start = 0xa0000000,
+ .end = 0xa0000008,
+ .flags = IORESOURCE_MEM,
+};
+
+#define NR_RESOURCES 2
+static struct resource *dsk_resources[NR_RESOURCES] = {
+ &_flash_res, &_cpld_async_res
+};
+
+
+/*----------------------------------------------------------------------*/
+
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = ARCH_PLL1_BASE,
+};
+
+static struct clk clkin1 = {
+ .name = "clkin1",
+ .rate = 50000000,
+ .node = LIST_HEAD_INIT(clkin1.node),
+ .children = LIST_HEAD_INIT(clkin1.children),
+ .childnode = LIST_HEAD_INIT(clkin1.childnode),
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &clkin1,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL | PLL_HAS_PREDIV,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 3,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 6,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV5,
+};
+
+static struct clk watchdog_clk = {
+ .name = "watchdog",
+ .parent = &pll1_sysclk3,
+};
+
+static struct clk core_clk = {
+ .name = "core",
+ .parent = &pll1_clk,
+};
+
+static struct clk_lookup evm_clks[] = {
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "core", &core_clk),
+ CLK("watchdog", NULL, &watchdog_clk),
+ CLK("", NULL, NULL)
+};
+
+/* Called from arch/kernel/setup.c */
+void c6x_board_setup_arch(void)
+{
+ int i;
+
+ printk(KERN_INFO "Designed for the DSK6455, Spectrum Digital Inc.\n");
+
+ /* Bootloader may not have setup EMIFA, so we do it here just in case */
+ DSCR_PERCFG1 = 3;
+ __delay(100);
+
+ /* CPLD */
+ EMIFA_CE2CFG = EMIFA_CFG_ASYNC |
+ EMIFA_CFG_W_SETUP(1) |
+ EMIFA_CFG_W_STROBE(10) |
+ EMIFA_CFG_W_HOLD(1) |
+ EMIFA_CFG_R_SETUP(1) |
+ EMIFA_CFG_R_STROBE(10) |
+ EMIFA_CFG_R_HOLD(1) |
+ EMIFA_CFG_WIDTH_8;
+
+ /* NOR Flash */
+ EMIFA_CE3CFG = EMIFA_CFG_ASYNC |
+ EMIFA_CFG_W_SETUP(1) |
+ EMIFA_CFG_W_STROBE(10) |
+ EMIFA_CFG_W_HOLD(1) |
+ EMIFA_CFG_R_SETUP(1) |
+ EMIFA_CFG_R_STROBE(10) |
+ EMIFA_CFG_R_HOLD(1) |
+ EMIFA_CFG_WIDTH_8;
+
+ /* Daughter Card */
+ EMIFA_CE4CFG = EMIFA_CFG_ASYNC |
+ EMIFA_CFG_W_SETUP(1) |
+ EMIFA_CFG_W_STROBE(10) |
+ EMIFA_CFG_W_HOLD(1) |
+ EMIFA_CFG_R_SETUP(1) |
+ EMIFA_CFG_R_STROBE(10) |
+ EMIFA_CFG_R_HOLD(1) |
+ EMIFA_CFG_WIDTH_32;
+
+ /* Daughter Card */
+ EMIFA_CE5CFG = EMIFA_CFG_ASYNC |
+ EMIFA_CFG_W_SETUP(1) |
+ EMIFA_CFG_W_STROBE(10) |
+ EMIFA_CFG_W_HOLD(1) |
+ EMIFA_CFG_R_SETUP(1) |
+ EMIFA_CFG_R_STROBE(10) |
+ EMIFA_CFG_R_HOLD(1) |
+ EMIFA_CFG_WIDTH_32;
+
+ /* Raise priority of waiting bus commands after 255 transfers */
+ EMIFA_BPRIO = 0xFE;
+
+ /* Initialize DSK6455 resources */
+ iomem_resource.name = "Memory";
+ for (i = 0; i < NR_RESOURCES; i++)
+ request_resource(&iomem_resource, dsk_resources[i]);
+
+ /* Initialize led register */
+ cpld_set_reg(DSK6455_CPLD_USER, 0x0);
+
+ c6x_clk_init(evm_clks);
+}
+
+/*
+ * NOR Flash support.
+ */
+#ifdef CONFIG_MTD
+static struct map_info nor_map = {
+ .name = "NOR-flash",
+ .phys = 0xB0000000,
+ .size = 0x400000,
+ .bankwidth = 1,
+};
+static struct mtd_info *mymtd;
+#ifdef CONFIG_MTD_PARTITIONS
+static int nr_parts;
+static struct mtd_partition *parts;
+static const char *part_probe_types[] = {
+ "cmdlinepart",
+ NULL
+};
+#endif
+
+static __init int nor_init(void)
+{
+ nor_map.virt = ioremap(nor_map.phys, nor_map.size);
+ simple_map_init(&nor_map);
+ mymtd = do_map_probe("cfi_probe", &nor_map);
+ if (mymtd) {
+ mymtd->owner = THIS_MODULE;
+
+#ifdef CONFIG_MTD_PARTITIONS
+ nr_parts = parse_mtd_partitions(mymtd,
+ part_probe_types,
+ &parts, 0);
+ if (nr_parts > 0)
+ add_mtd_partitions(mymtd, parts, nr_parts);
+ else
+ add_mtd_device(mymtd);
+#else
+ add_mtd_device(mymtd);
+#endif
+ }
+ return 0;
+}
+
+late_initcall(nor_init);
+#endif
diff --git a/arch/c6x/platforms/board-evm6457.c b/arch/c6x/platforms/board-evm6457.c
new file mode 100644
index 0000000..5d440fe
--- /dev/null
+++ b/arch/c6x/platforms/board-evm6457.c
@@ -0,0 +1,101 @@
+/*
+ * linux/arch/c6x/platforms/board-evm6457.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2008, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <asm/clock.h>
+#include <mach/board.h>
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = ARCH_PLL1_BASE,
+};
+
+static struct clk clkin1 = {
+ .name = "clkin1",
+ .rate = 60000000,
+ .node = LIST_HEAD_INIT(clkin1.node),
+ .children = LIST_HEAD_INIT(clkin1.children),
+ .childnode = LIST_HEAD_INIT(clkin1.childnode),
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &clkin1,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 3,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 6,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV4,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV5,
+};
+
+static struct clk core_clk = {
+ .name = "core",
+ .parent = &pll1_sysclk1,
+};
+
+static struct clk watchdog_clk = {
+ .name = "watchdog",
+ .parent = &pll1_sysclk5,
+};
+
+static struct clk_lookup evm_clks[] = {
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "core", &core_clk),
+ CLK("watchdog", NULL, &watchdog_clk),
+ CLK("", NULL, NULL)
+};
+
+/* Called from arch/kernel/setup.c */
+void c6x_board_setup_arch(void)
+{
+ printk(KERN_INFO "Designed for the EVM6457 board, Texas Instruments.\n");
+
+ c6x_clk_init(evm_clks);
+}
+
diff --git a/arch/c6x/platforms/board-evm6472.c b/arch/c6x/platforms/board-evm6472.c
new file mode 100644
index 0000000..ac49019
--- /dev/null
+++ b/arch/c6x/platforms/board-evm6472.c
@@ -0,0 +1,144 @@
+/*
+ * linux/arch/c6x/platforms/board-evm6472.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2008, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/platform_device.h>
+#include <asm/clock.h>
+#include <mach/board.h>
+
+/*----------------------------------------------------------------------*/
+
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = ARCH_PLL1_BASE,
+};
+
+static struct clk clkin1 = {
+ .name = "clkin1",
+ .rate = 25000000,
+ .node = LIST_HEAD_INIT(clkin1.node),
+ .children = LIST_HEAD_INIT(clkin1.children),
+ .childnode = LIST_HEAD_INIT(clkin1.childnode),
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &clkin1,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk1 = {
+ .name = "pll1_sysclk1",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk2 = {
+ .name = "pll1_sysclk2",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk3 = {
+ .name = "pll1_sysclk3",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk4 = {
+ .name = "pll1_sysclk4",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk5 = {
+ .name = "pll1_sysclk5",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk6 = {
+ .name = "pll1_sysclk6",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 3,
+};
+
+static struct clk pll1_sysclk8 = {
+ .name = "pll1_sysclk8",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 6,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 2,
+};
+
+static struct clk pll1_sysclk10 = {
+ .name = "pll1_sysclk10",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV10,
+};
+
+static struct clk watchdog_clk = {
+ .name = "watchdog",
+ .parent = &pll1_sysclk8,
+};
+
+static struct clk core_clk = {
+ .name = "core",
+ .parent = &pll1_sysclk1,
+};
+
+static struct clk_lookup evm_clks[] = {
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk1", &pll1_sysclk1),
+ CLK(NULL, "pll1_sysclk2", &pll1_sysclk2),
+ CLK(NULL, "pll1_sysclk3", &pll1_sysclk3),
+ CLK(NULL, "pll1_sysclk4", &pll1_sysclk4),
+ CLK(NULL, "pll1_sysclk5", &pll1_sysclk5),
+ CLK(NULL, "pll1_sysclk6", &pll1_sysclk6),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK(NULL, "pll1_sysclk8", &pll1_sysclk8),
+ CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
+ CLK(NULL, "pll1_sysclk10", &pll1_sysclk10),
+ CLK(NULL, "core", &core_clk),
+ CLK("watchdog", NULL, &watchdog_clk),
+ CLK(NULL, NULL, NULL)
+};
+
+/* Called from arch/kernel/setup.c */
+void c6x_board_setup_arch(void)
+{
+ printk(KERN_INFO "Designed for the EVM6472 board, Texas Instruments.\n");
+
+ c6x_clk_init(evm_clks);
+}
+
diff --git a/arch/c6x/platforms/board-evm6474.c b/arch/c6x/platforms/board-evm6474.c
new file mode 100644
index 0000000..35a616f
--- /dev/null
+++ b/arch/c6x/platforms/board-evm6474.c
@@ -0,0 +1,112 @@
+/*
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/platform_device.h>
+#include <asm/clock.h>
+#include <mach/board.h>
+
+/*----------------------------------------------------------------------*/
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = ARCH_PLL1_BASE,
+};
+
+static struct clk clkin1 = {
+ .name = "clkin1",
+/* .rate = 61440000, This is when using SYSCLK (SW5 CORE_CLOK_SEL to ON) */
+ .rate = 50000000, /* default one is 50MHz clock */
+ .node = LIST_HEAD_INIT(clkin1.node),
+ .children = LIST_HEAD_INIT(clkin1.children),
+ .childnode = LIST_HEAD_INIT(clkin1.childnode),
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &clkin1,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 3,
+};
+
+static struct clk pll1_sysclk10 = {
+ .name = "pll1_sysclk10",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 6,
+};
+
+static struct clk pll1_sysclk11 = {
+ .name = "pll1_sysclk11",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV11,
+};
+
+static struct clk pll1_sysclk12 = {
+ .name = "pll1_sysclk12",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 2,
+};
+
+static struct clk pll1_sysclk13 = {
+ .name = "pll1_sysclk13",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV13,
+};
+
+static struct clk core_clk = {
+ .name = "core",
+ .parent = &pll1_sysclk7,
+};
+
+static struct clk watchdog_clk = {
+ .name = "watchdog",
+ .parent = &pll1_sysclk10,
+};
+
+static struct clk_lookup evm_clks[] = {
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
+ CLK(NULL, "pll1_sysclk10", &pll1_sysclk10),
+ CLK(NULL, "pll1_sysclk11", &pll1_sysclk11),
+ CLK(NULL, "pll1_sysclk12", &pll1_sysclk12),
+ CLK(NULL, "pll1_sysclk13", &pll1_sysclk13),
+ CLK(NULL, "core", &core_clk),
+ CLK("watchdog", NULL, &watchdog_clk),
+ CLK("", NULL, NULL)
+};
+
+/* Called from arch/kernel/setup.c */
+void c6x_board_setup_arch(void)
+{
+ printk(KERN_INFO "Designed for the EVM6474 board, Texas Instruments.\n");
+
+ c6x_clk_init(evm_clks);
+}
+
diff --git a/arch/c6x/platforms/board-evm6474lite.c b/arch/c6x/platforms/board-evm6474lite.c
new file mode 100644
index 0000000..12cd4e3
--- /dev/null
+++ b/arch/c6x/platforms/board-evm6474lite.c
@@ -0,0 +1,110 @@
+/*
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Sandeep Paulraj <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+#include <linux/platform_device.h>
+#include <asm/clock.h>
+#include <mach/board.h>
+
+static struct pll_data pll1_data = {
+ .num = 1,
+ .phys_base = ARCH_PLL1_BASE,
+};
+
+static struct clk clkin1 = {
+ .name = "clkin1",
+ .rate = 50000000,
+ .node = LIST_HEAD_INIT(clkin1.node),
+ .children = LIST_HEAD_INIT(clkin1.children),
+ .childnode = LIST_HEAD_INIT(clkin1.childnode),
+};
+
+static struct clk pll1_clk = {
+ .name = "pll1",
+ .parent = &clkin1,
+ .pll_data = &pll1_data,
+ .flags = CLK_PLL,
+};
+
+static struct clk pll1_sysclk7 = {
+ .name = "pll1_sysclk7",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 1,
+};
+
+static struct clk pll1_sysclk9 = {
+ .name = "pll1_sysclk9",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 3,
+};
+
+static struct clk pll1_sysclk10 = {
+ .name = "pll1_sysclk10",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 6,
+};
+
+static struct clk pll1_sysclk11 = {
+ .name = "pll1_sysclk11",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV11,
+};
+
+static struct clk pll1_sysclk12 = {
+ .name = "pll1_sysclk12",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL | FIXED_DIV_PLL,
+ .div = 2,
+};
+
+static struct clk pll1_sysclk13 = {
+ .name = "pll1_sysclk13",
+ .parent = &pll1_clk,
+ .flags = CLK_PLL,
+ .div = PLLDIV13,
+};
+
+static struct clk core_clk = {
+ .name = "core",
+ .parent = &pll1_sysclk7,
+};
+
+static struct clk watchdog_clk = {
+ .name = "watchdog",
+ .parent = &pll1_sysclk10,
+};
+
+static struct clk_lookup evm_clks[] = {
+ CLK(NULL, "pll1", &pll1_clk),
+ CLK(NULL, "pll1_sysclk7", &pll1_sysclk7),
+ CLK(NULL, "pll1_sysclk9", &pll1_sysclk9),
+ CLK(NULL, "pll1_sysclk10", &pll1_sysclk10),
+ CLK(NULL, "pll1_sysclk11", &pll1_sysclk11),
+ CLK(NULL, "pll1_sysclk12", &pll1_sysclk12),
+ CLK(NULL, "pll1_sysclk13", &pll1_sysclk13),
+ CLK(NULL, "core", &core_clk),
+ CLK("watchdog", NULL, &watchdog_clk),
+ CLK("", NULL, NULL)
+};
+
+/* Called from arch/kernel/setup.c */
+void c6x_board_setup_arch(void)
+{
+ printk(KERN_INFO "Designed for the EVM6474 Lite EVM\n");
+
+ c6x_clk_init(evm_clks);
+}
+
diff --git a/arch/c6x/platforms/include/mach/board-dsk6455.h b/arch/c6x/platforms/include/mach/board-dsk6455.h
new file mode 100644
index 0000000..f2d2273
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/board-dsk6455.h
@@ -0,0 +1,53 @@
+/*
+ * linux/arch/c6x/platforms/mach/board-dsk6455.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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.
+ */
+
+/*
+ * Board memory
+ */
+#define BOARD_RAM_SIZE 0x08000000
+
+/*
+ * Timer definitions
+ */
+#define LINUX_TIMER_SRC TIMER_1
+#define LINUX_TIMER_IRQ IRQ_TINT1
+
+/*
+ * DSK6455 CPLD registers
+ */
+#define DSK6455_CPLD_REG_BASE 0xa0000000
+
+#define DSK6455_CPLD_USER 0x0
+#define DSK6455_CPLD_DC 0x1
+#define DSK6455_CPLD_VERSION 0x4
+#define DSK6455_CPLD_MISC 0x6
+#define DSK6455_CPLD_MISC2 0x7
+
+#ifndef __ASSEMBLY__
+#define cpld_setbit_reg(reg, val) \
+ (*((volatile unsigned char *) (DSK6455_CPLD_REG_BASE + (reg))) |= \
+ (unsigned char) (val))
+
+#define cpld_clearbit_reg(reg, val) \
+ (*((volatile unsigned char *) (DSK6455_CPLD_REG_BASE + (reg))) &= \
+ ~((unsigned char) (val)))
+
+#define cpld_set_reg(reg, val) \
+ (*((volatile unsigned char *) (DSK6455_CPLD_REG_BASE + (reg))) = \
+ (unsigned char) (val))
+
+#define cpld_get_reg(reg) \
+ (*((volatile unsigned char *) (DSK6455_CPLD_REG_BASE + (reg))))
+
+
+#endif
diff --git a/arch/c6x/platforms/include/mach/board-evm6457.h b/arch/c6x/platforms/include/mach/board-evm6457.h
new file mode 100644
index 0000000..cc6006c
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/board-evm6457.h
@@ -0,0 +1,25 @@
+/*
+ * linux/arch/c6x/platforms/mach/board-evm6457.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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.
+ */
+
+/*
+ * Board memory
+ */
+#define BOARD_RAM_SIZE 0x10000000
+
+/*
+ * Timer definitions
+ */
+#define LINUX_TIMER_SRC TIMER_1
+#define LINUX_TIMER_IRQ IRQ_TINT1
+
+
diff --git a/arch/c6x/platforms/include/mach/board-evm6472.h b/arch/c6x/platforms/include/mach/board-evm6472.h
new file mode 100644
index 0000000..5e33d30
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/board-evm6472.h
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/c6x/platforms/mach/board-evm6472.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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.
+ */
+
+/*
+ * Board memory
+ */
+#define BOARD_RAM_SIZE 0x10000000
+
+/*
+ * Timer definitions
+ */
+#define LINUX_TIMER_SRC (TIMER_0 + get_coreid())
+#define LINUX_TIMER_IRQ IRQ_TINT
diff --git a/arch/c6x/platforms/include/mach/board-evm6474.h b/arch/c6x/platforms/include/mach/board-evm6474.h
new file mode 100644
index 0000000..a5f8f94
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/board-evm6474.h
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/c6x/platforms/mach/board-evm6474.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Sandeep Paulraj <[email protected]>
+ *
+ * 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.
+ */
+
+/*
+ * Board memory
+ */
+#define BOARD_RAM_SIZE 0x08000000
+
+/*
+ * Timer definitions
+ */
+#define LINUX_TIMER_SRC (TIMER_5 - get_coreid())
+#define LINUX_TIMER_IRQ (IRQ_TINT5 - (get_coreid() << 1))
diff --git a/arch/c6x/platforms/include/mach/board-evm6474l.h b/arch/c6x/platforms/include/mach/board-evm6474l.h
new file mode 100644
index 0000000..a5f8f94
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/board-evm6474l.h
@@ -0,0 +1,23 @@
+/*
+ * linux/arch/c6x/platforms/mach/board-evm6474.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Sandeep Paulraj <[email protected]>
+ *
+ * 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.
+ */
+
+/*
+ * Board memory
+ */
+#define BOARD_RAM_SIZE 0x08000000
+
+/*
+ * Timer definitions
+ */
+#define LINUX_TIMER_SRC (TIMER_5 - get_coreid())
+#define LINUX_TIMER_IRQ (IRQ_TINT5 - (get_coreid() << 1))
diff --git a/arch/c6x/platforms/include/mach/board.h b/arch/c6x/platforms/include/mach/board.h
new file mode 100644
index 0000000..a03dd27
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/board.h
@@ -0,0 +1,32 @@
+/*
+ * linux/arch/c6x/platforms/mach/board.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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_C6X_BOARD_H
+#define __ASM_C6X_BOARD_H
+
+#ifdef CONFIG_ARCH_BOARD_DSK6455
+#include <mach/board-dsk6455.h>
+#endif
+#ifdef CONFIG_ARCH_BOARD_EVM6457
+#include <mach/board-evm6457.h>
+#endif
+#ifdef CONFIG_ARCH_BOARD_EVM6472
+#include <mach/board-evm6472.h>
+#endif
+#ifdef CONFIG_ARCH_BOARD_EVM6474
+#include <mach/board-evm6474.h>
+#endif
+#ifdef CONFIG_ARCH_BOARD_EVM6474L
+#include <mach/board-evm6474l.h>
+#endif
+
+#endif
diff --git a/arch/c6x/platforms/include/mach/cache.h b/arch/c6x/platforms/include/mach/cache.h
new file mode 100644
index 0000000..bc31a58
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/cache.h
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/cache.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2007, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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.
+ */
+
+/*
+ * Cache line size
+ */
+#define L1D_CACHE_BYTES 64
+#define L1P_CACHE_BYTES 32
+#define L2_CACHE_BYTES 128
+
+/*
+ * L2 used as cache
+ */
+#define L2MODE_SIZE L2MODE_256K_CACHE
+
+/*
+ * Internal Memory Control Registers for caches
+ */
+#define IMCR_CCFG 0x01840000
+#define IMCR_L1PCFG 0x01840020
+#define IMCR_L1PCC 0x01840024
+#define IMCR_L1DCFG 0x01840040
+#define IMCR_L1DCC 0x01840044
+#define IMCR_L2ALLOC0 0x01842000
+#define IMCR_L2ALLOC1 0x01842004
+#define IMCR_L2ALLOC2 0x01842008
+#define IMCR_L2ALLOC3 0x0184200c
+#define IMCR_L2WBAR 0x01844000
+#define IMCR_L2WWC 0x01844004
+#define IMCR_L2WIBAR 0x01844010
+#define IMCR_L2WIWC 0x01844014
+#define IMCR_L2IBAR 0x01844018
+#define IMCR_L2IWC 0x0184401c
+#define IMCR_L1PIBAR 0x01844020
+#define IMCR_L1PIWC 0x01844024
+#define IMCR_L1DWIBAR 0x01844030
+#define IMCR_L1DWIWC 0x01844034
+#define IMCR_L1DWBAR 0x01844040
+#define IMCR_L1DWWC 0x01844044
+#define IMCR_L1DIBAR 0x01844048
+#define IMCR_L1DIWC 0x0184404c
+#define IMCR_L2WB 0x01845000
+#define IMCR_L2WBINV 0x01845004
+#define IMCR_L2INV 0x01845008
+#define IMCR_L1PINV 0x01845028
+#define IMCR_L1DWB 0x01845040
+#define IMCR_L1DWBINV 0x01845044
+#define IMCR_L1DINV 0x01845048
+#define IMCR_MAR_BASE 0x01848000
+#define IMCR_MAR96_111 0x01848180
+#define IMCR_MAR128_191 0x01848200
+#define IMCR_MAR224_239 0x01848380
+#define IMCR_L2MPFAR 0x0184a000
+#define IMCR_L2MPFSR 0x0184a004
+#define IMCR_L2MPFCR 0x0184a008
+#define IMCR_L2MPLK0 0x0184a100
+#define IMCR_L2MPLK1 0x0184a104
+#define IMCR_L2MPLK2 0x0184a108
+#define IMCR_L2MPLK3 0x0184a10c
+#define IMCR_L2MPLKCMD 0x0184a110
+#define IMCR_L2MPLKSTAT 0x0184a114
+#define IMCR_L2MPPA_BASE 0x0184a200
+#define IMCR_L1PMPFAR 0x0184a400
+#define IMCR_L1PMPFSR 0x0184a404
+#define IMCR_L1PMPFCR 0x0184a408
+#define IMCR_L1PMPLK0 0x0184a500
+#define IMCR_L1PMPLK1 0x0184a504
+#define IMCR_L1PMPLK2 0x0184a508
+#define IMCR_L1PMPLK3 0x0184a50c
+#define IMCR_L1PMPLKCMD 0x0184a510
+#define IMCR_L1PMPLKSTAT 0x0184a514
+#define IMCR_L1PMPPA_BASE 0x0184a600
+#define IMCR_L1DMPFAR 0x0184ac00
+#define IMCR_L1DMPFSR 0x0184ac04
+#define IMCR_L1DMPFCR 0x0184ac08
+#define IMCR_L1DMPLK0 0x0184ad00
+#define IMCR_L1DMPLK1 0x0184ad04
+#define IMCR_L1DMPLK2 0x0184ad08
+#define IMCR_L1DMPLK3 0x0184ad0c
+#define IMCR_L1DMPLKCMD 0x0184ad10
+#define IMCR_L1DMPLKSTAT 0x0184ad14
+#define IMCR_L1DMPPA_BASE 0x0184ae00
+#define IMCR_L2PDWAKE0 0x0184c040
+#define IMCR_L2PDWAKE1 0x0184c044
+#define IMCR_L2PDSLEEP0 0x0184c050
+#define IMCR_L2PDSLEEP1 0x0184c054
+#define IMCR_L2PDSTAT0 0x0184c060
+#define IMCR_L2PDSTAT1 0x0184c064
+
+/*
+ * Physical memory granularity for MAR registers
+ */
+#define IMCR_MAR_SIZE 0x01000000
+
diff --git a/arch/c6x/platforms/include/mach/dscr.h b/arch/c6x/platforms/include/mach/dscr.h
new file mode 100644
index 0000000..1021e8a
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/dscr.h
@@ -0,0 +1,184 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/dscr.h
+ *
+ * DSCR definitions for Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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 __MACH_C6X_DSCR_H
+#define __MACH_C6X_DSCR_H
+
+#include <linux/bitops.h>
+#include <asm/hardware.h>
+
+/*
+ * Device State Control Registers
+ */
+#if defined(CONFIG_SOC_TMS320C6455)
+#define DSCR_DEVSTAT __SYSREG(0x02a80000, unsigned int)
+#define DSCR_PERLOCK __SYSREG(0x02ac0004, unsigned int)
+#define DSCR_PERCFG0 __SYSREG(0x02ac0008, unsigned int)
+#define DSCR_PERSTAT0 __SYSREG(0x02ac0014, unsigned int)
+#define DSCR_PERSTAT1 __SYSREG(0x02ac0018, unsigned int)
+#define DSCR_EMACCFG __SYSREG(0x02ac0020, unsigned int)
+#define DSCR_PERCFG1 __SYSREG(0x02ac002c, unsigned int)
+#define DSCR_EMUBUFPD __SYSREG(0x02ac0054, unsigned int)
+
+#define DSCR_LOCKVAL 0x0f0a0b00
+
+#define DSCR_B_PERCFG0_TCP BIT(0)
+#define DSCR_B_PERCFG0_VCP BIT(2)
+#define DSCR_B_PERCFG0_EMAC BIT(4)
+#define DSCR_B_PERCFG0_TIMER0 BIT(6)
+#define DSCR_B_PERCFG0_TIMER1 BIT(8)
+#define DSCR_B_PERCFG0_GPIO BIT(10)
+#define DSCR_B_PERCFG0_I2C BIT(12)
+#define DSCR_B_PERCFG0_BSP0 BIT(14)
+#define DSCR_B_PERCFG0_BSP1 BIT(16)
+#define DSCR_B_PERCFG0_HPI BIT(18)
+#define DSCR_B_PERCFG0_PCI BIT(20)
+#define DSCR_B_PERCFG0_UTOPIA BIT(22)
+
+#define DSCR_B_PERCFG1_EMIFA BIT(0)
+#define DSCR_B_PERCFG1_DDR2 BIT(1)
+
+#define DSCR_B_EMACCFG_RMIIRST (1<<19)
+
+#define DEVSTAT_MACSEL_OFFSET 9
+#define DEVSTAT_MACSEL_MASK 3
+
+#endif /* CONFIG_SOC_TMS320C6455 */
+
+#if defined(CONFIG_SOC_TMS320C6457)
+#define DSCR_JTAGID __SYSREG(0x02880818, unsigned int)
+#define DSCR_DEVSTAT __SYSREG(0x02880820, unsigned int)
+#define DSCR_KICK0 __SYSREG(0x02880838, unsigned int)
+#define DSCR_KICK1 __SYSREG(0x0288083c, unsigned int)
+#define DSCR_BOOTADDR __SYSREG(0x02880840, unsigned int)
+#define DSCR_DEVCFG __SYSREG(0x02880910, unsigned int)
+#define DSCR_MACID1 __SYSREG(0x02880914, unsigned int)
+#define DSCR_MACID2 __SYSREG(0x02880918, unsigned int)
+#define DSCR_PRI_ALLOC __SYSREG(0x0288091c, unsigned int)
+#define DSCR_WDRSTSEL __SYSREG(0x02880920, unsigned int)
+
+#define DSCR_KICK0_KEY 0x83E70B13
+#define DSCR_KICK1_KEY 0x95A4F1E0
+
+#define DSCR_B_DEVSTAT_LENDIAN BIT(0)
+#define DSCR_B_DEVSTAT_HPIWIDTH BIT(14)
+#define DSCR_B_DEVSTAT_ECLKINSEL BIT(15)
+
+/* Using SGMII */
+#define DEVSTAT_MACSEL_OFFSET 0
+#define DEVSTAT_MACSEL_MASK 0
+
+#endif /* CONFIG_SOC_TMS320C6457 */
+
+#if defined(CONFIG_SOC_TMS320C6474)
+#define DSCR_DEVSTAT __SYSREG(0x02880804, unsigned int)
+#define DSCR_JTAGID __SYSREG(0x02880814, unsigned int)
+#define DSCR_PERLOCK __SYSREG(0x02ac0004, unsigned int)
+#define DSCR_PERCFG0 __SYSREG(0x02ac0008, unsigned int)
+#define DSCR_PERSTAT0 __SYSREG(0x02ac0014, unsigned int)
+#define DSCR_PERSTAT1 __SYSREG(0x02ac0018, unsigned int)
+#define DSCR_EMACCFG __SYSREG(0x02ac0020, unsigned int)
+#define DSCR_PERCFG1 __SYSREG(0x02ac002c, unsigned int)
+#define DSCR_EMUBUFPD __SYSREG(0x02ac0054, unsigned int)
+
+#define DSCR_LOCKVAL 0x0f0a0b00
+
+#define DSCR_B_PERCFG0_TCP BIT(0)
+#define DSCR_B_PERCFG0_VCP BIT(2)
+#define DSCR_B_PERCFG0_EMAC BIT(4)
+#define DSCR_B_PERCFG0_TIMER0 BIT(6)
+#define DSCR_B_PERCFG0_TIMER1 BIT(8)
+#define DSCR_B_PERCFG0_GPIO BIT(10)
+#define DSCR_B_PERCFG0_I2C BIT(12)
+#define DSCR_B_PERCFG0_BSP0 BIT(14)
+#define DSCR_B_PERCFG0_BSP1 BIT(16)
+#define DSCR_B_PERCFG0_HPI BIT(18)
+#define DSCR_B_PERCFG0_PCI BIT(20)
+#define DSCR_B_PERCFG0_UTOPIA BIT(22)
+
+#define DSCR_B_PERCFG1_EMIFA BIT(0)
+#define DSCR_B_PERCFG1_DDR2 BIT(1)
+
+#define DSCR_B_EMACCFG_RMIIRST (1<<19)
+
+/* Using SGMII */
+#define DEVSTAT_MACSEL_OFFSET 0
+#define DEVSTAT_MACSEL_MASK 0
+
+#endif /* CONFIG_SOC_TMS320C6474 */
+
+#if defined(CONFIG_SOC_TMS320C6472)
+#define DSCR_DEVSTAT __SYSREG(0x2a80000, unsigned int)
+#define DSCR_PRIALLOC __SYSREG(0x2a80004, unsigned int)
+#define DSCR_DEVID __SYSREG(0x2a80008, unsigned int)
+#define DSCR_DEVCTL __SYSREG(0x2a80200, unsigned int)
+#define DSCR_PERLOCK __SYSREG(0x2a80204, unsigned int)
+#define DSCR_RMIIRESET0 __SYSREG(0x2a80208, unsigned int)
+#define DSCR_RMIIRESET1 __SYSREG(0x2a8020c, unsigned int)
+#define DSCR_HOSTPRIV __SYSREG(0x2a8040c, unsigned int)
+#define DSCR_PRIVPERM __SYSREG(0x2a8041c, unsigned int)
+#define DSCR_PRIVKEY __SYSREG(0x2a80420, unsigned int)
+#define DSCR_NMIGR0 __SYSREG(0x2a80500, unsigned int)
+#define DSCR_NMIGR1 __SYSREG(0x2a80504, unsigned int)
+#define DSCR_NMIGR2 __SYSREG(0x2a80508, unsigned int)
+#define DSCR_NMIGR3 __SYSREG(0x2a8050c, unsigned int)
+#define DSCR_NMIGR4 __SYSREG(0x2a80510, unsigned int)
+#define DSCR_NMIGR5 __SYSREG(0x2a80514, unsigned int)
+#define DSCR_IPCGR0 __SYSREG(0x2a80540, unsigned int)
+#define DSCR_IPCGR1 __SYSREG(0x2a80544, unsigned int)
+#define DSCR_IPCGR2 __SYSREG(0x2a80548, unsigned int)
+#define DSCR_IPCGR3 __SYSREG(0x2a8054c, unsigned int)
+#define DSCR_IPCGR4 __SYSREG(0x2a80550, unsigned int)
+#define DSCR_IPCGR5 __SYSREG(0x2a80554, unsigned int)
+#define DSCR_IPCGRH __SYSREG(0x2a8057c, unsigned int)
+#define DSCR_IPCAR0 __SYSREG(0x2a80580, unsigned int)
+#define DSCR_IPCAR1 __SYSREG(0x2a80584, unsigned int)
+#define DSCR_IPCAR2 __SYSREG(0x2a80588, unsigned int)
+#define DSCR_IPCAR3 __SYSREG(0x2a8058c, unsigned int)
+#define DSCR_IPCAR4 __SYSREG(0x2a80590, unsigned int)
+#define DSCR_IPCAR5 __SYSREG(0x2a80594, unsigned int)
+#define DSCR_IPCARH __SYSREG(0x2a805bc, unsigned int)
+#define DSCR_TPMGR __SYSREG(0x2a80714, unsigned int)
+#define DSCR_RSTMUX0 __SYSREG(0x2a80718, unsigned int)
+#define DSCR_RSTMUX1 __SYSREG(0x2a8071c, unsigned int)
+#define DSCR_RSTMUX2 __SYSREG(0x2a80720, unsigned int)
+#define DSCR_RSTMUX3 __SYSREG(0x2a80724, unsigned int)
+#define DSCR_RSTMUX4 __SYSREG(0x2a80728, unsigned int)
+#define DSCR_RSTMUX5 __SYSREG(0x2a8072c, unsigned int)
+
+#define DSCR_LOCKVAL 0xa1e183a
+
+#define DSCR_B_DEVCTL_EMAC1 BIT(12)
+
+#define DEVSTAT_B_EMAC0_MACSEL 0x00000700
+#define DEVSTAT_B_EMAC0_OFFSET 8
+#define DEVSTAT_B_EMAC1_MACSEL 0x00C00000
+#define DEVSTAT_B_EMAC1_OFFSET 22
+
+#define DEVSTAT_MACSEL_OFFSET 8
+#define DEVSTAT_MACSEL_MASK 7
+
+#endif /* CONFIG_SOC_TMS320C6472 */
+
+/*
+ * MDIO interfaces
+ */
+#define DEVSTAT_MACSEL_MII 0
+#define DEVSTAT_MACSEL_RMII 1
+#define DEVSTAT_MACSEL_GMII 2
+#define DEVSTAT_MACSEL_RGMII 3
+#define DEVSTAT_MACSEL_S3MII 5
+#define DEVSTAT_MACSEL_DISABLE 7
+
+#endif /* __MACH_C6X_DSCR_H */
+
diff --git a/arch/c6x/platforms/include/mach/emif.h b/arch/c6x/platforms/include/mach/emif.h
new file mode 100644
index 0000000..056d206
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/emif.h
@@ -0,0 +1,63 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/emif.h
+ *
+ * External Memory Interface for Texas Instruments C64x+
+ *
+ * Copyright (C) 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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 __MACH_C6X_EMIF_H
+#define __MACH_C6X_EMIF_H
+
+#if defined(CONFIG_SOC_TMS320C6455)
+#define EMIFA_BASE 0x70000000
+#elif defined(CONFIG_SOC_TMS320C6457)
+#define EMIFA_BASE 0x70000000
+#else
+#error "EMIFA not supported on this SoC"
+#endif
+
+#define EMIFA_MIDR __SYSREG(EMIFA_BASE + 0x00, uint32_t)
+#define EMIFA_STAT __SYSREG(EMIFA_BASE + 0x04, uint32_t)
+#define EMIFA_BPRIO __SYSREG(EMIFA_BASE + 0x20, uint32_t)
+#define EMIFA_CE2CFG __SYSREG(EMIFA_BASE + 0x80, uint32_t)
+#define EMIFA_CE3CFG __SYSREG(EMIFA_BASE + 0x84, uint32_t)
+#define EMIFA_CE4CFG __SYSREG(EMIFA_BASE + 0x88, uint32_t)
+#define EMIFA_CE5CFG __SYSREG(EMIFA_BASE + 0x8C, uint32_t)
+#define EMIFA_AWCC __SYSREG(EMIFA_BASE + 0xA0, uint32_t)
+#define EMIFA_INTRAW __SYSREG(EMIFA_BASE + 0xC0, uint32_t)
+#define EMIFA_INTMSK __SYSREG(EMIFA_BASE + 0xC4, uint32_t)
+#define EMIFA_INTMSKSET __SYSREG(EMIFA_BASE + 0xC8, uint32_t)
+#define EMIFA_INTMSKCLR __SYSREG(EMIFA_BASE + 0x0C, uint32_t)
+
+/* Layout of CEnCFG register for Sync mode */
+#define EMIFA_CFG_SYNC BIT(31)
+#define EMIFA_CFG_RD_BE_EN BIT(10)
+#define EMIFA_CFG_CE_EXT BIT(9)
+#define EMIFA_CFG_R_ENABLE BIT(8)
+#define EMIFA_CFG_W_LTNCY(n) (((n) & 3) << 6)
+#define EMIFA_CFG_R_LTNCY(n) (((n) & 3) << 2)
+#define EMIFA_CFG_WIDTH_8 0
+#define EMIFA_CFG_WIDTH_16 1
+#define EMIFA_CFG_WIDTH_32 2
+#define EMIFA_CFG_WIDTH_64 3
+
+/* Layout of CEnCFG register for Async mode */
+#define EMIFA_CFG_ASYNC (0 << 31)
+#define EMIFA_CFG_SS BIT(30)
+#define EMIFA_CFG_BWEM BIT(29)
+#define EMIFA_CFG_AE BIT(28)
+#define EMIFA_CFG_W_SETUP(n) ((((n) - 1) & 0x0f) << 24)
+#define EMIFA_CFG_W_STROBE(n) ((((n) - 1) & 0x3f) << 18)
+#define EMIFA_CFG_W_HOLD(n) ((((n) - 1) & 0x07) << 15)
+#define EMIFA_CFG_R_SETUP(n) ((((n) - 1) & 0x0f) << 11)
+#define EMIFA_CFG_R_STROBE(n) ((((n) - 1) & 0x3f) << 5)
+#define EMIFA_CFG_R_HOLD(n) ((((n) - 1) & 0x07) << 2)
+/* Bus width same as Sync mode */
+
+
+#endif /* __MACH_C6X_EMIF_H */
diff --git a/arch/c6x/platforms/include/mach/gemac.h b/arch/c6x/platforms/include/mach/gemac.h
new file mode 100644
index 0000000..ba82036
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/gemac.h
@@ -0,0 +1,763 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/gemac.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ * Aurelien Jacquiot <[email protected]>
+ *
+ * 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 __MACH_C6X_GEMAC_H
+#define __MACH_C6X_GEMAC_H
+
+#include <linux/io.h>
+#include <mach/board.h>
+
+/*
+ * Packet flags (16 bits)
+ */
+#define EMAC_DESC_FLAG_SOP 0x80000000
+#define EMAC_DESC_FLAG_EOP 0x40000000
+#define EMAC_DESC_FLAG_OWNER 0x20000000
+#define EMAC_DESC_FLAG_EOQ 0x10000000
+#define EMAC_DESC_FLAG_TDOWNCMPLT 0x08000000
+#define EMAC_DESC_FLAG_PASSCRC 0x04000000
+#define EMAC_DESC_FLAG_JABBER 0x02000000
+#define EMAC_DESC_FLAG_OVERSIZE 0x01000000
+#define EMAC_DESC_FLAG_FRAGMENT 0x00800000
+#define EMAC_DESC_FLAG_UNDERSIZED 0x00400000
+#define EMAC_DESC_FLAG_CONTROL 0x00200000
+#define EMAC_DESC_FLAG_OVERRUN 0x00100000
+#define EMAC_DESC_FLAG_CODEERROR 0x00080000
+#define EMAC_DESC_FLAG_ALIGNERROR 0x00040000
+#define EMAC_DESC_FLAG_CRCERROR 0x00020000
+#define EMAC_DESC_FLAG_NOMATCH 0x00010000
+
+#define EMAC_PACKET_LEN_MASK 0x000007FF
+
+/*
+ * EMAC registers
+ */
+#define EMAC_TXIDVER 0x000 /* TX ID and Version */
+#define EMAC_TXCONTROL 0x004 /* TX Control */
+#define EMAC_TXTEARDOWN 0x008 /* TX Teardown */
+#define EMAC_RXIDVER 0x010 /* RX ID and Version */
+#define EMAC_RXCONTROL 0x014 /* RX Control */
+#define EMAC_RXTEARDOWN 0x018 /* RX Teardown */
+#define EMAC_TXINTSTATRAW 0x080 /* TX IRQ Status Register (Unmasked) */
+#define EMAC_TXINTSTATMASKED 0x084 /* TX IRQ Status Register (Masked) */
+#define EMAC_TXINTMASKSET 0x088 /* TX Interrupt Mask Set Register */
+#define EMAC_TXINTMASKCLEAR 0x08C /* TX Interrupt Mask Clear Register */
+#define EMAC_MACINVECTOR 0x090 /* MAC Input Vector Register */
+#define EMAC_MACEOIVECTOR 0x094 /* MAC End of IRQ Vector Register */
+#define EMAC_RXINTSTATRAW 0x0A0 /* RX IRQ Status Register (Unmasked) */
+#define EMAC_RXINTSTATMASKED 0x0A4 /* RX IRQ Status Register (Masked) */
+#define EMAC_RXINTMASKSET 0x0A8 /* RX IRQ Mask Set Register */
+#define EMAC_RXINTMASKCLEAR 0x0AC /* RX IRQ Mask Clear Register */
+#define EMAC_MACINTSTATRAW 0x0B0 /* MAC IRQ Status Register (Unmasked) */
+#define EMAC_MACINTSTATMASKED 0x0B4 /* MAC IRQ Status Register (Masked) */
+#define EMAC_MACINTMASKSET 0x0B8 /* MAC IRQ Mask Set Register */
+#define EMAC_MACINTMASKCLEAR 0x0BC /* MAC IRQ Mask Clear Register */
+#define EMAC_RXMBPENABLE 0x100 /* RX Mulicast/Bcast/Promisc Enable */
+#define EMAC_RXUNICASTSET 0x104 /* RX Unicast Set Register */
+#define EMAC_RXUNICASTCLEAR 0x108 /* RX Unicast Clear Register */
+#define EMAC_RXMAXLEN 0x10c /* RX Maximum Length Register */
+#define EMAC_RXBUFFEROFFSET 0x110 /* RX Buffer Offset Register */
+#define EMAC_RXFILTERLOWTHRESH 0x114 /* RX Filer Low Priority Packets Threshhold */
+#define EMAC_RX0FLOWTHRESH 0x120 /* RX Channel 0 Flow Control Threshhold */
+#define EMAC_RX1FLOWTHRESH 0x124 /* RX Channel 1 Flow Control Threshhold */
+#define EMAC_RX2FLOWTHRESH 0x128 /* RX Channel 2 Flow Control Threshhold */
+#define EMAC_RX3FLOWTHRESH 0x12c /* RX Channel 3 Flow Control Threshhold */
+#define EMAC_RX4FLOWTHRESH 0x130 /* RX Channel 4 Flow Control Threshhold */
+#define EMAC_RX5FLOWTHRESH 0x134 /* RX Channel 5 Flow Control Threshhold */
+#define EMAC_RX6FLOWTHRESH 0x138 /* RX Channel 6 Flow Control Threshhold */
+#define EMAC_RX7FLOWTHRESH 0x13c /* RX Channel 7 Flow Control Threshhold */
+#define EMAC_RX0FREEBUFFER 0x140 /* RX Channel 0 Free Buffer Count Register */
+#define EMAC_RX1FREEBUFFER 0x144 /* RX Channel 1 Free Buffer Count Register */
+#define EMAC_RX2FREEBUFFER 0x148 /* RX Channel 2 Free Buffer Count Register */
+#define EMAC_RX3FREEBUFFER 0x14c /* RX Channel 3 Free Buffer Count Register */
+#define EMAC_RX4FREEBUFFER 0x150 /* RX Channel 4 Free Buffer Count Register */
+#define EMAC_RX5FREEBUFFER 0x154 /* RX Channel 5 Free Buffer Count Register */
+#define EMAC_RX6FREEBUFFER 0x158 /* RX Channel 6 Free Buffer Count Register */
+#define EMAC_RX7FREEBUFFER 0x15c /* RX Channel 7 Free Buffer Count Register */
+#define EMAC_MACCONTROL 0x160 /* MAC Control Register */
+#define EMAC_MACSTATUS 0x164 /* MAC Status Register */
+#define EMAC_EMCONTROL 0x168 /* Emulation Control Register */
+#define EMAC_FIFOCONTROL 0x16C /* FIFO Control Register */
+#define EMAC_MACCONFIG 0x170 /* MAC Configuration Register */
+#define EMAC_SOFTRESET 0x174 /* Soft Reset Register */
+#define EMAC_MACSRCADDRLO 0x1D0 /* MAC Source Address Low Bytes Register */
+#define EMAC_MACSRCADDRHI 0x1D4 /* MAC Source Address High Bytes Register */
+#define EMAC_MACHASH1 0x1D8 /* MAC Address Hash 1 Register */
+#define EMAC_MACHASH2 0x1DC /* MAC Address Hash 2 Register */
+#define EMAC_BOFFTEST 0x1E0 /* Backoff Test Register */
+#define EMAC_TPACETEST 0x1E4 /* Transmit Pacing Test Register */
+#define EMAC_RXPAUSE 0x1E8 /* Receive Pause Timer Register */
+#define EMAC_TXPAUSE 0x1EC /* Transmit Pause Timer Register */
+#define EMAC_RXGOODFRAMES 0x200 /* Number of Good Frames Received */
+#define EMAC_RXBCASTFRAMES 0x204 /* Number of Good Broadcast Frames Received */
+#define EMAC_RXMCASTFRAMES 0x208 /* Number of Good Multicast Frames Received */
+#define EMAC_RXPAUSEFRAMES 0x20c /* Number of PauseRX Frames Received */
+#define EMAC_RXCRCERRORS 0x210 /* Number of Frames Received with CRC Errors */
+#define EMAC_RXALIGNCODEERRORS 0x214 /* Number of Frames Received with Alignment/Code Errors */
+#define EMAC_RXOVERSIZED 0x218 /* Number of Oversized Frames Received */
+#define EMAC_RXJABBER 0x21c /* Number of Jabber Frames Received */
+#define EMAC_RXUNDERSIZED 0x220 /* Number of Undersized Frames Received */
+#define EMAC_RXFRAGMENTS 0x224 /* Number of RX Frame Fragments Received */
+#define EMAC_RXFILTERED 0x228 /* Number of RX Frames Filtered Based on Address */
+#define EMAC_RXQOSFILTERED 0x22c /* Number of RX Frames Filtered Based on QoS Filtering */
+#define EMAC_RXOCTETS 0x230 /* Total Number of Received Bytes in Good Frames */
+#define EMAC_TXGOODFRAMES 0x234 /* Number of Good Frames Sent */
+#define EMAC_TXBCASTFRAMES 0x238 /* Number of Good Broadcast Frames Sent */
+#define EMAC_TXMCASTFRAMES 0x23c /* Number of Good Multicast Frames Sent */
+#define EMAC_TXPAUSEFRAMES 0x240 /* Number of PauseTX Frames Sent */
+#define EMAC_TXDEFERRED 0x244 /* Number of Frames Where Transmission was Deferred */
+#define EMAC_TXCOLLISION 0x248 /* Total Number of Frames Sent That Experienced a Collision */
+#define EMAC_TXSINGLECOLL 0x24c /* Number of Frames Sent with Exactly One Collision */
+#define EMAC_TXMULTICOLL 0x250 /* Number of Frames Sent with Multiple Colisions */
+#define EMAC_TXEXCESSIVECOLL 0x254 /* Number of TX Frames Lost Due to Excessive Collisions */
+#define EMAC_TXLATECOLL 0x258 /* Number of TX Frames Lost Due to a Late Collision */
+#define EMAC_TXUNDERRUN 0x25c /* Number of TX Frames Lost with Transmit Underrun Error */
+#define EMAC_TXCARRIERSLOSS 0x260 /* Numebr of TX Frames Lost Due to Carrier Sense Loss */
+#define EMAC_TXOCTETS 0x264 /* Total Nu,ber of Transmitted Bytes in Good Frames */
+#define EMAC_FRAME64 0x268 /* Total TX & RX Frames with Octet Size of 64 */
+#define EMAC_FRAME65T127 0x26c /* Total TX & RX Frames with Octet Size of 65 to 127 */
+#define EMAC_FRAME128T255 0x270 /* Total TX & RX Frames with Octet Size of 128 to 255 */
+#define EMAC_FRAME256T511 0x274 /* Total TX & RX Frames with Octet Size of 256 to 511 */
+#define EMAC_FRAME512T1023 0x278 /* Total TX & RX Frames with Octet Size of 512 to 1023 */
+#define EMAC_FRAME1024TUP 0x27c /* Total TX & RX Frames with Octet Size of 1024 or above */
+#define EMAC_NETOCTETS 0x280 /* Sum of all Octets Sent or Received on the Network */
+#define EMAC_RXSOFOVERRUNS 0x284 /* Total RX Start of Frame Overruns (FIFO or DMA) */
+#define EMAC_RXMOFOVERRUNS 0x288 /* Total RX Middle of Frame Overruns (FIFO or DMA) */
+#define EMAC_RXDMAOVERRUNS 0x28c /* Total RX DMA Overruns */
+#define EMAC_MACADDRLO 0x500 /* MAC Address Low Bytes Register (rcv match) */
+#define EMAC_MACADDRHI 0x504 /* MAC Address High Bytes Register (rcv match) */
+#define EMAC_MACINDEX 0x508 /* MAC Index Register */
+#define EMAC_TX0HDP 0x600 /* TX Channel 0 DMA Head Descriptor Pointer Register */
+#define EMAC_TX1HDP 0x604 /* TX Channel 1 DMA Head Descriptor Pointer Register */
+#define EMAC_TX2HDP 0x608 /* TX Channel 2 DMA Head Descriptor Pointer Register */
+#define EMAC_TX3HDP 0x60c /* TX Channel 3 DMA Head Descriptor Pointer Register */
+#define EMAC_TX4HDP 0x610 /* TX Channel 4 DMA Head Descriptor Pointer Register */
+#define EMAC_TX5HDP 0x614 /* TX Channel 5 DMA Head Descriptor Pointer Register */
+#define EMAC_TX6HDP 0x618 /* TX Channel 6 DMA Head Descriptor Pointer Register */
+#define EMAC_TX7HDP 0x61c /* TX Channel 7 DMA Head Descriptor Pointer Register */
+#define EMAC_RX0HDP 0x620 /* RX Channel 0 DMA Head Descriptor Pointer Register */
+#define EMAC_RX1HDP 0x624 /* RX Channel 1 DMA Head Descriptor Pointer Register */
+#define EMAC_RX2HDP 0x628 /* RX Channel 2 DMA Head Descriptor Pointer Register */
+#define EMAC_RX3HDP 0x62c /* RX Channel 3 DMA Head Descriptor Pointer Register */
+#define EMAC_RX4HDP 0x630 /* RX Channel 4 DMA Head Descriptor Pointer Register */
+#define EMAC_RX5HDP 0x634 /* RX Channel 5 DMA Head Descriptor Pointer Register */
+#define EMAC_RX6HDP 0x638 /* RX Channel 6 DMA Head Descriptor Pointer Register */
+#define EMAC_RX7HDP 0x63c /* RX Channel 7 DMA Head Descriptor Pointer Register */
+#define EMAC_TX0INTACK 0x640 /* TX Channel 0 Interrupt Acknowledge Register */
+#define EMAC_TX1INTACK 0x644 /* TX Channel 1 Interrupt Acknowledge Register */
+#define EMAC_TX2INTACK 0x648 /* TX Channel 2 Interrupt Acknowledge Register */
+#define EMAC_TX3INTACK 0x64c /* TX Channel 3 Interrupt Acknowledge Register */
+#define EMAC_TX4INTACK 0x650 /* TX Channel 4 Interrupt Acknowledge Register */
+#define EMAC_TX5INTACK 0x654 /* TX Channel 5 Interrupt Acknowledge Register */
+#define EMAC_TX6INTACK 0x658 /* TX Channel 6 Interrupt Acknowledge Register */
+#define EMAC_TX7INTACK 0x65c /* TX Channel 7 Interrupt Acknowledge Register */
+#define EMAC_RX0INTACK 0x660 /* RX Channel 0 Interrupt Acknowledge Register */
+#define EMAC_RX1INTACK 0x664 /* RX Channel 1 Interrupt Acknowledge Register */
+#define EMAC_RX2INTACK 0x668 /* RX Channel 2 Interrupt Acknowledge Register */
+#define EMAC_RX3INTACK 0x66c /* RX Channel 3 Interrupt Acknowledge Register */
+#define EMAC_RX4INTACK 0x670 /* RX Channel 4 Interrupt Acknowledge Register */
+#define EMAC_RX5INTACK 0x674 /* RX Channel 5 Interrupt Acknowledge Register */
+#define EMAC_RX6INTACK 0x678 /* RX Channel 6 Interrupt Acknowledge Register */
+#define EMAC_RX7INTACK 0x67c /* RX Channel 7 Interrupt Acknowledge Register */
+
+
+#if !(defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457))
+
+#if defined(CONFIG_SOC_TMS320C6472)
+#define EMAC_EMIC_PID 0x1000
+#define EMAC_PSCFG 0x1004
+#define EMAC_RSVD0 0x1008
+#define EMAC_EWINTCTL0 0x1020 /* Ethernet Wrapper: Interrupt Control Register */
+#define EMAC_RSVD1 0x1034
+#define EMAC_RPCFG0 0x10fc
+#define EMAC_RPSTAT0 0x111c
+#define EMAC_TPCFG0 0x113c
+#define EMAC_TPSTAT0 0x115c
+
+#define EMAC_B_HOST (1 << 1)
+#define EMAC_B_STAT (1 << 2)
+#define EMAC_B_MDIOLINT (1 << 3)
+#define EMAC_B_MDIOUSER (1 << 4)
+#define EMAC_B_TX0 (1 << 8)
+#define EMAC_B_RX0 (1 << 16)
+
+#else /* defined(CONFIG_SOC_TMS320C6472) */
+
+#define EMAC_EWCTL 0x1004 /* Interrupt Control Register */
+#define EMAC_EWINTTCNT 0x1008 /* Interrupt Timer Count */
+
+#endif /* defined(CONFIG_SOC_TMS320C6472) */
+
+#else /* !(defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457)) */
+
+#define ECTL_IDVER 0x00
+#define ECTL_SOFTRESET 0x04
+#define ECTL_EMCONTROL 0x08
+#define ECTL_INTCONTROL 0x0c
+#define ECTL_RXTHRESTEN 0x10
+#define ECTL_RXEN 0x14
+#define ECTL_TXEN 0x18
+#define ECTL_MISCEN 0x1c
+
+#define ECTL_RXTHRESTSTAT 0x40
+#define ECTL_RXSTAT 0x44
+#define ECTL_TXSTAT 0x48
+#define ECTL_MISCSTAT 0x4c
+#define ECTL_RXIMAX 0x70
+#define ECTL_TXIMAX 0x74
+
+#endif /* !(defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457)) */
+
+#define EMAC_NUM_STATREGS 36
+
+/* Bit fields of EMAC registers */
+
+#define EMAC_B_INTEN (1 << 0) /* for EWCTL */
+
+#define EMAC_B_SOFTRST (1 << 0) /* for SOFTRESET */
+
+#define EMAC_B_MULTEN (1 << 5)
+#define EMAC_B_BROADEN (1 << 13)
+#define EMAC_B_RXCAFEN (1 << 21)
+#define EMAC_B_RXCEFEN (1 << 22)
+#define EMAC_B_RXCSFEN (1 << 23)
+#define EMAC_B_RXCMFEN (1 << 24)
+#define EMAC_B_RXNOCHAIN (1 << 28)
+#define EMAC_B_RXQOSEN (1 << 29)
+#define EMAC_B_RXPASSCRC (1 << 30) /* for RXMBPENABLE */
+
+#define EMAC_B_FULLDUPLEX (1 << 0)
+#define EMAC_B_LOOPBACK (1 << 1)
+#define EMAC_B_RXBUFERFLOWEN (1 << 3)
+#define EMAC_B_TXFLOWEN (1 << 4)
+#define EMAC_B_GMIIEN (1 << 5)
+#define EMAC_B_TXPACE (1 << 6)
+#define EMAC_B_GIG (1 << 7)
+#define EMAC_B_TXPTYPE (1 << 9)
+#define EMAC_B_CMDIDLE (1 << 11)
+#define EMAC_B_RXFIFOFLOWEN (1 << 12)
+#define EMAC_B_RXOWNERSHIP (1 << 13)
+#define EMAC_B_RXOFFLENBLOCK (1 << 14)
+#define EMAC_B_RMIISPEED (1 << 15)
+#define EMAC_B_RMIIDUPLEXMODE (1 << 16)
+#define EMAC_B_GIGFORCE (1 << 17)
+#define EMAC_B_RGMIIEN (1 << 18)
+#define EMAC_B_CTL_EN (1 << 18)
+#define EMAC_B_EXTEN (1 << 18) /* for MACCONTROL */
+
+#define EMAC_B_STATINT (1 << 0)
+#define EMAC_B_HOSTINT (1 << 1) /* for MACINTMASKSET */
+
+#if defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457)
+#define EMAC_B_RXPEND0 (1 << 0) /* for MACINVECTOR */
+#define EMAC_B_RXTHRESPEND0 (1 << 8)
+#define EMAC_B_TXPEND0 (1 << 16)
+#define EMAC_B_USERINT (1 << 24)
+#define EMAC_B_LINKINT (1 << 25)
+#define EMAC_B_HOSTPEND (1 << 26)
+#define EMAC_B_STATPEND (1 << 27)
+#else /* defined(CONFIG_SOC_TMS320C6474) */
+#define EMAC_B_TXPEND0 (1 << 0)
+#define EMAC_B_RXPEND0 (1 << 8)
+#define EMAC_B_STATPEND (1 << 16)
+#define EMAC_B_HOSTPEND (1 << 17) /* for MACINVECTOR */
+#endif /* defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457) */
+
+#define EMAC_V_SOPERROR 1
+#define EMAC_V_OWNERSHIP 2
+#define EMAC_V_NOEOP 3
+#define EMAC_V_NULLPTR 4
+#define EMAC_V_NULLLEN 5
+#define EMAC_V_LENRRROR 6
+#define EMAC_S_RXERRCH 8
+#define EMAC_S_TXERRCH 16
+#define EMAC_S_RXERRCODE 12
+#define EMAC_S_TXERRCODE 20
+#define EMAC_M_RXERRCH 0x00000700
+#define EMAC_M_TXERRCH 0x00070000
+#define EMAC_M_RXERRCODE 0x0000f000
+#define EMAC_M_TXERRCODE 0x00f00000 /* for MACSTATUS */
+
+#define EMAC_S_VALID 20
+#define EMAC_S_MATCHFILTER 19
+#define EMAC_S_CHANNEL 16 /* for MACADDRLO */
+
+/* Configuration mode flags */
+#define EMAC_CONFIG_CHPRIORITY 0x01 /* use Tx channel priority */
+#define EMAC_CONFIG_MACLOOPBACK 0x02 /* MAC internal loopback */
+#define EMAC_CONFIG_RXCRC 0x04 /* include CRC in RX frames */
+#define EMAC_CONFIG_TXCRC 0x08 /* Tx frames include CRC */
+#define EMAC_CONFIG_PASSERROR 0x10 /* pass error frames */
+#define EMAC_CONFIG_PASSCONTROL 0x20 /* pass control frames */
+#define EMAC_CONFIG_PACING 0x40 /* use interrupt pacing */
+
+#if defined(CONFIG_SGMII)
+
+/*
+ * SGMII registers
+ */
+#define SGMII_REG_BASE 0x02c40000
+#define SGMII_IDVER_REG (SGMII_REG_BASE + 0x000)
+#define SGMII_SRESET_REG (SGMII_REG_BASE + 0x004)
+#define SGMII_CTL_REG (SGMII_REG_BASE + 0x010)
+#define SGMII_STATUS_REG (SGMII_REG_BASE + 0x014)
+#define SGMII_MRADV_REG (SGMII_REG_BASE + 0x018)
+#define SGMII_LPADV_REG (SGMII_REG_BASE + 0x020)
+#define SGMII_TXCFG_REG (SGMII_REG_BASE + 0x030)
+#define SGMII_RXCFG_REG (SGMII_REG_BASE + 0x034)
+#define SGMII_AUXCFG_REG (SGMII_REG_BASE + 0x038)
+
+#endif /* CONFIG_SGMII*/
+
+#if defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457)
+
+/*
+ * TCI6488/C6474/C6457 dependent definitions
+ */
+#define EMAC0_REG_BASE 0x02c80000
+#define ECTL0_REG_BASE 0x02c81000
+#define EMAC0_DSC_BASE 0x02c82000
+
+#define EMAC_MAX_INSTANCE 1
+#define PTR_TO_HW(x) (x)
+#define HW_TO_PTR(x) (x)
+#define _INTFLAG 0
+#define get_emac_idx() (get_coreid())
+
+#define emac_arch_get_hash1() emac_get_reg(EMAC_MACHASH1)
+#define emac_arch_get_hash2() emac_get_reg(EMAC_MACHASH2)
+#define emac_arch_get_promisc() (emac_get_reg(EMAC_RXMBPENABLE) & EMAC_B_RXCAFEN)
+#define emac_arch_get_control() (emac_get_reg(EMAC_MACCONTROL) & \
+ (EMAC_B_FULLDUPLEX | EMAC_B_RMIIDUPLEXMODE | \
+ EMAC_B_GIG | EMAC_B_RMIISPEED))
+#define emac_arch_set_hash1(a) emac_set_reg(EMAC_MACHASH1, a)
+#define emac_arch_set_hash2(a) emac_set_reg(EMAC_MACHASH2, a)
+#define emac_arch_set_promisc(a) if (a) emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN)
+#define emac_arch_set_control(a) if (a) emac_setbit_reg(EMAC_MACCONTROL, a)
+
+#define emac_arch_init_control(pace) \
+ emac_setbit_reg(EMAC_MACCONTROL, (pace) ? EMAC_B_EXTEN | EMAC_B_GMIIEN | EMAC_B_TXPACE : \
+ EMAC_B_EXTEN | EMAC_B_GMIIEN)
+
+#define ectl_arch_rx_irq_enter(c) ectl_clearbit_reg(ECTL_RXEN + (get_coreid() << 4), \
+ 1 << (c))
+#define ectl_arch_rx_irq_leave(c) do { \
+ emac_set_reg(EMAC_MACEOIVECTOR, 0x1 + (get_coreid() << 2)); \
+ ectl_setbit_reg(ECTL_RXEN + (get_coreid() << 4), 1 << (c)); \
+ } while (0)
+#define ectl_arch_tx_irq_enter(c) ectl_clearbit_reg(ECTL_TXEN + (get_coreid() << 4), \
+ 1 << (c))
+#define ectl_arch_tx_irq_leave(c) do { \
+ emac_set_reg(EMAC_MACEOIVECTOR, 0x2 + (get_coreid() << 2)); \
+ ectl_setbit_reg(ECTL_TXEN + (get_coreid() << 4), 1 << (c)); \
+ } while (0)
+
+#define ectl_arch_enable_irq(c, misc) do { \
+ if (misc) \
+ ectl_set_reg(ECTL_MISCEN + (get_coreid() << 4), 0x3); \
+ ectl_setbit_reg(ECTL_RXEN + (get_coreid() << 4), 1 << (c)); \
+ ectl_setbit_reg(ECTL_TXEN + (get_coreid() << 4), 1 << (c)); \
+ } while (0)
+
+#define ectl_arch_disable_irq(c) do { \
+ ectl_set_reg(ECTL_MISCEN + (get_coreid() << 4), 0); \
+ ectl_clearbit_reg(ECTL_RXEN + (get_coreid() << 4), 1 << (c)); \
+ ectl_clearbit_reg(ECTL_TXEN + (get_coreid() << 4), 1 << (c)); \
+ } while (0)
+
+
+#define emac_arch_get_int_vector() emac_get_reg(EMAC_MACINVECTOR)
+#define emac_arch_get_pending_irq(i, f, c) ((i) & ((f) << (c)))
+#define emac_arch_enable_irq(reg, c) emac_set_reg(reg, 1 << (c))
+
+#define emac_arch_reset_switch()
+
+#define emac_arch_reset_ectl() do { \
+ ectl_set_reg(ECTL_INTCONTROL, 0); \
+ ectl_set_reg(ECTL_SOFTRESET, 1); \
+ while (ectl_get_reg(ECTL_SOFTRESET) != 0) \
+ ; \
+ } while (0)
+
+#define emac_arch_set_pacing() do { \
+ ectl_set_reg(ECTL_INTCONTROL, gemac_int_prescaler()); \
+ ectl_setbit_reg(ECTL_INTCONTROL, (0x3 << (get_coreid() << 1)) << 16); \
+ ectl_set_reg(ECTL_RXIMAX + (get_coreid() << 3), 0x10); \
+ ectl_set_reg(ECTL_TXIMAX + (get_coreid() << 3), 0x10); \
+ } while (0)
+
+#define emac_arch_clear_mac_addr() \
+ for (i = 0; i < 32; i++) { \
+ emac_set_reg(EMAC_MACINDEX, i); \
+ emac_set_reg(EMAC_MACADDRHI, 0); \
+ emac_set_reg(EMAC_MACADDRLO, 0); \
+ }
+
+#define emac_arch_set_mac_addr_index(i) emac_set_reg(EMAC_MACINDEX, i)
+#define emac_arch_set_mac_addr_high(a) emac_set_reg(EMAC_MACADDRHI, a)
+#define emac_arch_set_mac_addr_low(a) emac_set_reg(EMAC_MACADDRLO, a)
+#define emac_arch_get_mac_addr_high(a) emac_get_reg(EMAC_MACADDRHI)
+#define emac_arch_get_mac_addr_low(a) emac_get_reg(EMAC_MACADDRLO)
+
+static inline int emac_check_shared_capability(void)
+{
+#ifdef C6X_SOC_HAS_CORE_REV
+ if (arch_get_silicon_rev() < 0x3)
+ printk(KERN_WARNING "Warning sharing of GEMAC has issues with silicon rev %s!\n",
+ arch_compute_silicon_rev(arch_get_silicon_rev()));
+#endif
+ return 1;
+}
+
+#ifdef CONFIG_SOC_TMS320C6457
+#include <mach/dscr.h>
+#define EFUSE_REG_MAC_ADDR DSCR_MACID1
+#endif
+#ifdef CONFIG_SOC_TMS320C6474
+#define EFUSE_REG_MAC_ADDR 0x2880834
+#endif
+
+#define emac_arch_get_mac_addr emac_arch_get_mac_addr_from_efuse
+
+#define EMAC_HAS_SEPARATE_RXTX_IRQS
+#define EMAC_ARCH_HAS_MAC_ADDR
+
+#elif defined(CONFIG_SOC_TMS320C6472)
+
+/*
+ * TCI6486/C6472 dependent definitions
+ */
+#include <mach/dscr.h>
+
+#define EMAC0_REG_BASE 0x02c80000
+#define ECTL0_REG_BASE 0x02c81000
+#define EMAC0_DSC_BASE 0x02c82000
+
+#define EMAC1_REG_BASE 0x02cc0000
+#define ECTL1_REG_BASE 0x02cc1000
+#define EMAC1_DSC_BASE 0x02cc2000
+
+#define EMAC_MAX_INSTANCE 2
+#define PTR_TO_HW(x) (x)
+#define HW_TO_PTR(x) (x)
+#define _INTFLAG IRQF_DISABLED
+#define get_emac_idx() (get_coreid())
+
+#define emac_arch_get_hash1() emac_get_reg(EMAC_MACHASH1)
+#define emac_arch_get_hash2() emac_get_reg(EMAC_MACHASH2)
+#define emac_arch_get_promisc() (emac_get_reg(EMAC_RXMBPENABLE) & EMAC_B_RXCAFEN)
+#define emac_arch_get_control() emac_get_reg(EMAC_MACCONTROL)
+#define emac_arch_set_hash1(a) emac_set_reg(EMAC_MACHASH1, a)
+#define emac_arch_set_hash2(a) emac_set_reg(EMAC_MACHASH2, a)
+#define emac_arch_set_promisc(a) if (a) emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN)
+#define emac_arch_set_control(a) if (a) emac_setbit_reg(EMAC_MACCONTROL, a)
+
+#define emac_arch_init_control(pace) do { \
+ unsigned int dev_stat = DSCR_DEVSTAT; \
+ unsigned int gigabit = 0, macsel; \
+ if (dev->dev_id == 0) { \
+ macsel = (dev_stat & DEVSTAT_B_EMAC0_MACSEL) >> \
+ DEVSTAT_B_EMAC0_OFFSET; \
+ if ((macsel == DEVSTAT_MACSEL_GMII) || \
+ (macsel == DEVSTAT_MACSEL_RGMII)) \
+ gigabit = 1; \
+ } \
+ if (dev->dev_id == 1) { \
+ macsel = (dev_stat & DEVSTAT_B_EMAC1_MACSEL) >> \
+ DEVSTAT_B_EMAC1_OFFSET; \
+ if (macsel == DEVSTAT_MACSEL_GMII) \
+ gigabit = 1; \
+ } \
+ if (gigabit == 1) \
+ emac_set_reg(EMAC_MACCONTROL, EMAC_B_GIG | EMAC_B_RGMIIEN); \
+ else \
+ emac_set_reg(EMAC_MACCONTROL, EMAC_B_RMIISPEED); \
+ emac_setbit_reg(EMAC_MACCONTROL, (pace) ? \
+ (EMAC_B_GMIIEN | EMAC_B_TXPACE) : \
+ EMAC_B_GMIIEN); \
+ } while (0)
+
+#define ectl_arch_rx_irq_enter(c)
+#define ectl_arch_rx_irq_leave(c)
+#define ectl_arch_tx_irq_enter(c)
+#define ectl_arch_tx_irq_leave(c)
+#define ectl_arch_enable_irq(c, misc) \
+do { \
+ if (misc) \
+ emac_set_reg(EMAC_EWINTCTL0 + (get_coreid() << 2), \
+ EMAC_B_STAT | EMAC_B_HOST | \
+ (EMAC_B_TX0 << (c)) | (EMAC_B_RX0 << (c))); \
+ else \
+ emac_set_reg(EMAC_EWINTCTL0 + (get_coreid() << 2), \
+ (EMAC_B_TX0 << (c)) | (EMAC_B_RX0 << (c))); \
+} while (0)
+
+#define ectl_arch_disable_irq(c) \
+ emac_set_reg(EMAC_EWINTCTL0 + (get_coreid() << 2), 0)
+
+/*
+ * On Tomahawk, MACINVECTOR can be null even if TX/RX int occurs.
+ * This is probably an hardware bug.
+ */
+#define emac_arch_get_int_vector() (emac_get_reg(EMAC_MACINVECTOR) \
+ | ((emac_get_reg(EMAC_RXINTSTATMASKED) & 0xff) << 8) \
+ | (emac_get_reg(EMAC_TXINTSTATMASKED) & 0xff))
+#define emac_arch_get_pending_irq(i, f, c) ((i) & ((f) << (c)))
+#define emac_arch_enable_irq(reg, c) emac_set_reg(reg, (1 << (c + 16)) | (1 << c))
+
+#define emac_arch_reset_switch()
+
+/* Disable EMAC/MDIO interrupts in EMIC */
+#define emac_arch_reset_ectl() emac_set_reg(EMAC_EWINTCTL0 + (get_coreid() << 2), 0x0)
+
+#define emac_arch_set_pacing() do { \
+ emac_set_reg(EMAC_RPCFG0 + (get_coreid() << 2), 0x3); \
+ emac_set_reg(EMAC_TPCFG0 + (get_coreid() << 2), 0x3); \
+ emac_set_reg(EMAC_PSCFG, gemac_int_prescaler()); \
+ } while (0)
+
+#define emac_arch_clear_mac_addr() \
+ for (i = 0; i < 32; i++) { \
+ emac_set_reg(EMAC_MACINDEX, i); \
+ emac_set_reg(EMAC_MACADDRHI, 0); \
+ emac_set_reg(EMAC_MACADDRLO, 0); \
+ }
+
+#define emac_arch_set_mac_addr_index(i) emac_set_reg(EMAC_MACINDEX, i)
+#define emac_arch_set_mac_addr_high(a) emac_set_reg(EMAC_MACADDRHI, a)
+#define emac_arch_set_mac_addr_low(a) emac_set_reg(EMAC_MACADDRLO, a)
+#define emac_arch_get_mac_addr_high(a) emac_get_reg(EMAC_MACADDRHI)
+#define emac_arch_get_mac_addr_low(a) emac_get_reg(EMAC_MACADDRLO)
+
+#define emac_check_shared_capability() 1
+
+#define EFUSE_REG_MAC_ADDR 0x2a80700
+#define emac_arch_get_mac_addr emac_arch_get_mac_addr_from_efuse
+
+#define EMAC_HAS_SEPARATE_RXTX_IRQS
+#define EMAC_ARCH_HAS_MAC_ADDR
+
+#elif defined(CONFIG_SOC_TMS320C6455)
+
+/*
+ * C6455 dependent definitions
+ */
+#include <mach/dscr.h>
+
+#define EMAC0_REG_BASE 0x02c80000
+#define ECTL0_REG_BASE 0x02c81000
+#define EMAC0_DSC_BASE 0x02c82000
+
+#define EMAC_MAX_INSTANCE 1
+#define PTR_TO_HW(x) (x)
+#define HW_TO_PTR(x) (x)
+#define _INTFLAG 0
+#define get_emac_idx() 0
+
+#define emac_arch_get_hash1() emac_get_reg(EMAC_MACHASH1)
+#define emac_arch_get_hash2() emac_get_reg(EMAC_MACHASH2)
+#define emac_arch_get_promisc() (emac_get_reg(EMAC_RXMBPENABLE) & EMAC_B_RXCAFEN)
+#define emac_arch_get_control() (emac_get_reg(EMAC_MACCONTROL) & \
+ (EMAC_B_FULLDUPLEX | EMAC_B_RMIIDUPLEXMODE | \
+ EMAC_B_GIG | EMAC_B_RMIISPEED))
+#define emac_arch_set_hash1(a) emac_set_reg(EMAC_MACHASH1, a)
+#define emac_arch_set_hash2(a) emac_set_reg(EMAC_MACHASH2, a)
+#define emac_arch_set_promisc(a) \
+ do { \
+ if (a) \
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN); \
+ } while (0)
+#define emac_arch_set_control(a) \
+ do { \
+ if (a) \
+ emac_setbit_reg(EMAC_MACCONTROL, a); \
+ } while (0)
+#define emac_arch_init_control(pace) \
+ emac_setbit_reg(EMAC_MACCONTROL, (pace) ? \
+ (EMAC_B_GMIIEN | EMAC_B_TXPACE) : \
+ EMAC_B_GMIIEN)
+
+#define ectl_arch_rx_irq_enter(c)
+#define ectl_arch_rx_irq_leave(c)
+#define ectl_arch_tx_irq_enter(c)
+#define ectl_arch_tx_irq_leave(c)
+#define ectl_arch_enable_irq(c, misc) emac_setbit_reg(EMAC_EWCTL, EMAC_B_INTEN)
+#define ectl_arch_disable_irq(c) emac_clearbit_reg(EMAC_EWCTL, EMAC_B_INTEN)
+
+#define emac_arch_get_int_vector() emac_get_reg(EMAC_MACINVECTOR)
+#define emac_arch_get_pending_irq(i, f, c) ((i) & ((f) << (c)))
+#define emac_arch_enable_irq(reg, c) emac_set_reg(reg, 1 << (c))
+
+#define emac_arch_reset_switch()
+
+/* Disable EMAC/MDIO interrupts and reset EMAC/MDIO modules */
+#define emac_arch_reset_ectl() emac_clearbit_reg(EMAC_EWCTL, EMAC_B_INTEN)
+
+#define emac_arch_set_pacing() do { \
+ /* Wait at least 100 cycles */ \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ /* Set interrupt timer count (decremented at cpuclk/6) */ \
+ emac_set_reg(EMAC_EWINTTCNT, 15000); \
+ } while (0)
+
+#define emac_arch_clear_mac_addr() \
+ for (i = 0; i < 32; i++) { \
+ emac_set_reg(EMAC_MACINDEX, i); \
+ emac_set_reg(EMAC_MACADDRHI, 0); \
+ emac_set_reg(EMAC_MACADDRLO, 0); \
+ }
+
+#define emac_arch_set_mac_addr_index(i) emac_set_reg(EMAC_MACINDEX, i)
+#define emac_arch_set_mac_addr_high(a) emac_set_reg(EMAC_MACADDRHI, a)
+#define emac_arch_set_mac_addr_low(a) emac_set_reg(EMAC_MACADDRLO, a)
+#define emac_arch_get_mac_addr_high(a) emac_get_reg(EMAC_MACADDRHI)
+#define emac_arch_get_mac_addr_low(a) emac_get_reg(EMAC_MACADDRLO)
+
+/* Take RMII out of reset (the following 2 settings apply only to PG 2.0) */
+#define rmii_arch_fix() do { \
+ if (intfmacsel == DEVSTAT_MACSEL_RMII) \
+ DSCR_EMACCFG |= DSCR_B_EMACCFG_RMIIRST; \
+ } while (0)
+
+#define emac_check_shared_capability() 0
+
+#define EMAC_TIMER_TICK_MDIO
+#define EMAC_DO_INIT_MDIO
+
+#else
+
+/*
+ * Generic definitions
+ */
+
+#define EMAC0_REG_BASE 0x02c80000
+#define ECTL0_REG_BASE 0x02c81000
+#define EMAC0_DSC_BASE 0x02c82000
+
+#define EMAC_MAX_INSTANCE 1
+#define PTR_TO_HW(x) (x)
+#define HW_TO_PTR(x) (x)
+#define _INTFLAG 0
+#define get_emac_idx() 0
+
+#define emac_arch_get_hash1() emac_get_reg(EMAC_MACHASH1)
+#define emac_arch_get_hash2() emac_get_reg(EMAC_MACHASH2)
+#define emac_arch_get_promisc() (emac_get_reg(EMAC_RXMBPENABLE) & EMAC_B_RXCAFEN)
+#define emac_arch_get_control() (emac_get_reg(EMAC_MACCONTROL) & \
+ (EMAC_B_FULLDUPLEX | EMAC_B_RMIIDUPLEXMODE | \
+ EMAC_B_GIG | EMAC_B_RMIISPEED))
+#define emac_arch_set_hash1(a) emac_set_reg(EMAC_MACHASH1, a)
+#define emac_arch_set_hash2(a) emac_set_reg(EMAC_MACHASH2, a)
+#define emac_arch_set_promisc(a) \
+ do { \
+ if (a) \
+ emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN); \
+ } while (0)
+#define emac_arch_set_control(a) \
+ do { \
+ if (a) \
+ emac_setbit_reg(EMAC_MACCONTROL, a); \
+ } while (0)
+#define emac_arch_init_control(pace) \
+ emac_setbit_reg(EMAC_MACCONTROL, (pace) ? \
+ (EMAC_B_GMIIEN | EMAC_B_TXPACE) : \
+ EMAC_B_GMIIEN)
+
+#define ectl_arch_rx_irq_enter(c)
+#define ectl_arch_rx_irq_leave(c)
+#define ectl_arch_tx_irq_enter(c)
+#define ectl_arch_tx_irq_leave(c)
+#define ectl_arch_enable_irq(c, misc) emac_setbit_reg(EMAC_EWCTL, EMAC_B_INTEN)
+#define ectl_arch_disable_irq(c) emac_clearbit_reg(EMAC_EWCTL, EMAC_B_INTEN)
+
+#define emac_arch_get_int_vector() emac_get_reg(EMAC_MACINVECTOR)
+#define emac_arch_get_pending_irq(i, f, c) ((i) & ((f) << (c)))
+#define emac_arch_enable_irq(reg, c) emac_set_reg(reg, 1 << (c))
+
+#define emac_arch_reset_switch()
+
+/* Disable EMAC/MDIO interrupts and reset EMAC/MDIO modules */
+#define emac_arch_reset_ectl() emac_clearbit_reg(EMAC_EWCTL, EMAC_B_INTEN)
+
+#define emac_arch_set_pacing() do { \
+ /* Wait at least 100 cycles */ \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ emac_get_reg(EMAC_EWINTTCNT); \
+ /* Set interrupt timer count (decremented at cpuclk/6) */ \
+ emac_set_reg(EMAC_EWINTTCNT, 15000); \
+ } while (0)
+
+#define emac_arch_clear_mac_addr() \
+ for (i = 0; i < 32; i++) { \
+ emac_set_reg(EMAC_MACINDEX, i); \
+ emac_set_reg(EMAC_MACADDRHI, 0); \
+ emac_set_reg(EMAC_MACADDRLO, 0); \
+ }
+
+#define emac_arch_set_mac_addr_index(i) emac_set_reg(EMAC_MACINDEX, i)
+#define emac_arch_set_mac_addr_high(a) emac_set_reg(EMAC_MACADDRHI, a)
+#define emac_arch_set_mac_addr_low(a) emac_set_reg(EMAC_MACADDRLO, a)
+#define emac_arch_get_mac_addr_high(a) emac_get_reg(EMAC_MACADDRHI)
+#define emac_arch_get_mac_addr_low(a) emac_get_reg(EMAC_MACADDRLO)
+
+#define emac_check_shared_capability() 0
+
+#define rmii_arch_fix()
+
+#define EMAC_TIMER_TICK_MDIO
+#define EMAC_DO_INIT_MDIO
+
+#endif
+
+#ifdef EFUSE_REG_MAC_ADDR
+
+#define EFUSE_REG1 __SYSREG(EFUSE_REG_MAC_ADDR + 4, unsigned int)
+#define EFUSE_REG0 __SYSREG(EFUSE_REG_MAC_ADDR, unsigned int)
+
+/* Read the e-fuse value as 32 bit values to be endian independent */
+static inline int emac_arch_get_mac_addr_from_efuse(char *x)
+{
+ unsigned int addr0, addr1;
+
+ addr1 = EFUSE_REG1;
+ addr0 = EFUSE_REG0;
+
+#if defined(CONFIG_SOC_TMS320C6472)
+ x[0] = (addr0 & 0xff000000) >> 24;
+ x[1] = (addr0 & 0x00ff0000) >> 16;
+ x[2] = (addr0 & 0x0000ff00) >> 8;
+ x[3] = addr0 & 0x000000ff;
+ x[4] = (addr1 & 0xff000000) >> 24;
+ x[5] = (addr1 & 0x00ff0000) >> 16;
+#elif defined(CONFIG_SOC_TMS320C6474) || defined(CONFIG_SOC_TMS320C6457)
+ x[0] = (addr1 & 0x0000ff00) >> 8;
+ x[1] = addr1 & 0x000000ff;
+ x[2] = (addr0 & 0xff000000) >> 24;
+ x[3] = (addr0 & 0x00ff0000) >> 16;
+ x[4] = (addr0 & 0x0000ff00) >> 8;
+ x[5] = addr0 & 0x000000ff;
+#else
+#error "Missing SoC support for emac_arch_get_mac_addr"
+#endif
+ return 0;
+}
+#endif /* EFUSE_REG_MAC_ADDR */
+
+#endif /* __MACH_C6X_GEMAC_H */
diff --git a/arch/c6x/platforms/include/mach/gmdio.h b/arch/c6x/platforms/include/mach/gmdio.h
new file mode 100644
index 0000000..aad05ee
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/gmdio.h
@@ -0,0 +1,18 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/gmdio.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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 __MACH_C6X_GMDIO_H
+#define __MACH_C6X_GMDIO_H
+
+#define MDIO_REG_BASE 0x02c81800
+
+#endif /* __MACH_C6X_GMDIO_H */
diff --git a/arch/c6x/platforms/include/mach/hardware.h b/arch/c6x/platforms/include/mach/hardware.h
new file mode 100644
index 0000000..526962c
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/hardware.h
@@ -0,0 +1,194 @@
+/*
+ * linux/arch/c6x/mach-evm6486/include/mach/hardware.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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_C6X_MACH_HARDWARE_H
+#define __ASM_C6X_MACH_HARDWARE_H
+
+/*
+ * Misc. hardware defines which should probably have their own home
+ * so we can get rid of hardware.h altogether.
+ */
+
+/*
+ * Memory address space
+ */
+#if defined(CONFIG_SOC_TMS320C6455)
+#define RAM_EMIFA_CE2 0xa0000000
+#define RAM_EMIFA_CE3 0xb0000000
+#define RAM_EMIFA_CE4 0xc0000000
+#define RAM_EMIFA_CE5 0xd0000000
+#define RAM_DDR2_CE0 0xe0000000
+#define RAM_MEMORY_START RAM_DDR2_CE0
+
+#elif defined(CONFIG_SOC_TMS320C6457)
+#define RAM_EMIFA_CE2 0xa0000000
+#define RAM_EMIFA_CE3 0xb0000000
+#define RAM_EMIFA_CE4 0xc0000000
+#define RAM_EMIFA_CE5 0xd0000000
+#define RAM_DDR2_CE0 0xe0000000
+#define RAM_MEMORY_START RAM_DDR2_CE0
+
+#elif defined(CONFIG_SOC_TMS320C6472)
+#define RAM_SRAM 0x00800000
+#define RAM_SRAM_BASE 0x10800000
+#define RAM_SRAM_OFFSET 0x01000000
+#define RAM_SRAM_SIZE 0x00100000
+#define RAM_EMIFA_CE2 0xa0000000
+#define RAM_EMIFA_CE3 0xb0000000
+#define RAM_EMIFA_CE4 0xc0000000
+#define RAM_EMIFA_CE5 0xd0000000
+#define RAM_DDR2_CE0 0xe0000000
+#define RAM_MEMORY_START RAM_DDR2_CE0
+
+#elif defined(CONFIG_SOC_TMS320C6474)
+#define RAM_SRAM 0x00800000
+#define RAM_SRAM_BASE 0x10800000
+#define RAM_SRAM_OFFSET 0x01000000
+#define RAM_SRAM_SIZE 0x00100000
+#define RAM_EMIFA_CE2 0xa0000000
+#define RAM_EMIFA_CE3 0xb0000000
+#define RAM_EMIFA_CE4 0xc0000000
+#define RAM_EMIFA_CE5 0xd0000000
+#define RAM_DDR2_CE0 0x80000000
+#define RAM_MEMORY_START RAM_DDR2_CE0
+
+#else
+#error "No SoC memory address space defines"
+#endif
+
+/*
+ * VBUS clock Rate in MHz (1-255)
+ */
+#define VBUSCLK 165
+
+/*
+ * GPIO registers base
+ */
+#define GPIO_REG_BASE 0x02b00000
+
+/*
+ * PSC Registers
+ */
+#if defined(CONFIG_SOC_TMS320C6474)
+#define PSC_PTCMD __SYSREG(0x02ac0120, unsigned int)
+#define PSC_PDSTAT0 __SYSREG(0x02ac0200, unsigned int)
+#define PSC_PDSTAT1 __SYSREG(0x02ac0204, unsigned int)
+#define PSC_PDSTAT2 __SYSREG(0x02ac0208, unsigned int)
+#define PSC_PDSTAT3 __SYSREG(0x02ac020c, unsigned int)
+#define PSC_PDSTAT4 __SYSREG(0x02ac0210, unsigned int)
+#define PSC_PDSTAT5 __SYSREG(0x02ac0214, unsigned int)
+#define PSC_PDCTL0 __SYSREG(0x02ac0300, unsigned int)
+#define PSC_PDCTL1 __SYSREG(0x02ac0304, unsigned int)
+#define PSC_PDCTL2 __SYSREG(0x02ac0308, unsigned int)
+#define PSC_PDCTL3 __SYSREG(0x02ac030c, unsigned int)
+#define PSC_PDCTL4 __SYSREG(0x02ac0310, unsigned int)
+#define PSC_PDCTL5 __SYSREG(0x02ac0314, unsigned int)
+#define PSC_MDSTAT0 __SYSREG(0x02ac0800, unsigned int)
+#define PSC_MDSTAT1 __SYSREG(0x02ac0804, unsigned int)
+#define PSC_MDSTAT2 __SYSREG(0x02ac0808, unsigned int)
+#define PSC_MDSTAT3 __SYSREG(0x02ac080c, unsigned int)
+#define PSC_MDSTAT4 __SYSREG(0x02ac0810, unsigned int)
+#define PSC_MDSTAT5 __SYSREG(0x02ac0814, unsigned int)
+#define PSC_MDSTAT6 __SYSREG(0x02ac0818, unsigned int)
+#define PSC_MDSTAT7 __SYSREG(0x02ac081c, unsigned int)
+#define PSC_MDSTAT8 __SYSREG(0x02ac0820, unsigned int)
+#define PSC_MDSTAT9 __SYSREG(0x02ac0824, unsigned int)
+#define PSC_MDSTAT10 __SYSREG(0x02ac0828, unsigned int)
+#define PSC_MDCTL0 __SYSREG(0x02ac0a00, unsigned int)
+#define PSC_MDCTL1 __SYSREG(0x02ac0a04, unsigned int)
+#define PSC_MDCTL2 __SYSREG(0x02ac0a08, unsigned int)
+#define PSC_MDCTL3 __SYSREG(0x02ac0a0c, unsigned int)
+#define PSC_MDCTL4 __SYSREG(0x02ac0a10, unsigned int)
+#define PSC_MDCTL5 __SYSREG(0x02ac0a14, unsigned int)
+#define PSC_MDCTL6 __SYSREG(0x02ac0a18, unsigned int)
+#define PSC_MDCTL7 __SYSREG(0x02ac0a1c, unsigned int)
+#define PSC_MDCTL8 __SYSREG(0x02ac0a20, unsigned int)
+#define PSC_MDCTL9 __SYSREG(0x02ac0a24, unsigned int)
+#define PSC_MDCTL10 __SYSREG(0x02ac0a28, unsigned int)
+#define PSC_MDCTL11 __SYSREG(0x02ac0a2c, unsigned int)
+#endif /* CONFIG_SOC_TMS320C6474 */
+
+#if defined(CONFIG_SOC_TMS320C6472)
+#define PSC_PID __SYSREG(0x02ae0000, unsigned int)
+#define PSC_INTEVAL __SYSREG(0x02ae0018, unsigned int)
+#define PSC_MERRPR __SYSREG(0x02ae0040, unsigned int)
+#define PSC_MERRCR __SYSREG(0x02ae0050, unsigned int)
+#define PSC_PTCMD __SYSREG(0x02ae0120, unsigned int)
+#define PSC_PTSTAT __SYSREG(0x02ae0128, unsigned int)
+#define PSC_MDSTAT0 __SYSREG(0x02ae0800, unsigned int)
+#define PSC_MDSTAT1 __SYSREG(0x02ae0804, unsigned int)
+#define PSC_MDSTAT2 __SYSREG(0x02ae0808, unsigned int)
+#define PSC_MDSTAT3 __SYSREG(0x02ae080c, unsigned int)
+#define PSC_MDSTAT4 __SYSREG(0x02ae0810, unsigned int)
+#define PSC_MDSTAT5 __SYSREG(0x02ae0814, unsigned int)
+#define PSC_MDSTAT6 __SYSREG(0x02ae0818, unsigned int)
+#define PSC_MDSTAT7 __SYSREG(0x02ae081c, unsigned int)
+#define PSC_MDSTAT8 __SYSREG(0x02ae0820, unsigned int)
+#define PSC_MDSTAT9 __SYSREG(0x02ae0824, unsigned int)
+#define PSC_MDSTAT10 __SYSREG(0x02ae0828, unsigned int)
+#define PSC_MDSTAT11 __SYSREG(0x02ae082c, unsigned int)
+#define PSC_MDSTAT12 __SYSREG(0x02ae0830, unsigned int)
+#define PSC_MDSTAT13 __SYSREG(0x02ae0834, unsigned int)
+#define PSC_MDCTL0 __SYSREG(0x02ae0a00, unsigned int)
+#define PSC_MDCTL1 __SYSREG(0x02ae0a04, unsigned int)
+#define PSC_MDCTL2 __SYSREG(0x02ae0a08, unsigned int)
+#define PSC_MDCTL3 __SYSREG(0x02ae0a0c, unsigned int)
+#define PSC_MDCTL4 __SYSREG(0x02ae0a10, unsigned int)
+#define PSC_MDCTL5 __SYSREG(0x02ae0a14, unsigned int)
+#define PSC_MDCTL6 __SYSREG(0x02ae0a18, unsigned int)
+#define PSC_MDCTL7 __SYSREG(0x02ae0a1c, unsigned int)
+#define PSC_MDCTL8 __SYSREG(0x02ae0a20, unsigned int)
+#define PSC_MDCTL9 __SYSREG(0x02ae0a24, unsigned int)
+#define PSC_MDCTL10 __SYSREG(0x02ae0a28, unsigned int)
+#define PSC_MDCTL11 __SYSREG(0x02ae0a2c, unsigned int)
+#define PSC_MDCTL12 __SYSREG(0x02ae0a30, unsigned int)
+#define PSC_MDCTL13 __SYSREG(0x02ae0a34, unsigned int)
+#endif /* CONFIG_SOC_TMS320C6472 */
+
+/*
+ * TCI648x megamodules misc registers & constants
+ */
+#define MM_REVID 0x01812000
+
+#if defined(CONFIG_SOC_TMS320C6474)
+#define CORE_NUM 3
+#define C6X_SOC_HAS_CORE_REV
+#elif defined(CONFIG_SOC_TMS320C6472)
+#define CORE_NUM 6
+#else
+#define CORE_NUM 1
+#endif
+
+/*
+ * Inter-DSP Interrupt Registers
+ */
+#if defined(CONFIG_SOC_TMS320C6474)
+#define IPCGR_BASE 0x02880900
+#define IPCAR_BASE 0x02880940
+#endif
+#if defined(CONFIG_SOC_TMS320C6472)
+#define NMIGR_BASE 0x02a80500
+#define IPCGR_BASE 0x02a80540
+#define IPCAR_BASE 0x02a80580
+#endif
+
+#if defined(CONFIG_SOC_TMS320C6474)
+/*
+ * MCBSP registers base
+ */
+#define MCBSP0_BASE_ADDR 0x028c0000
+#define MCBSP1_BASE_ADDR 0x028d0000
+#define MCBSP0_EDMA_BASE_ADDR 0x30000000
+#define MCBSP1_EDMA_BASE_ADDR 0x34000000
+#endif
+
+#endif /* __ASM_C6X_MACH_HARDWARE_H */
diff --git a/arch/c6x/platforms/include/mach/irq-c645x.h b/arch/c6x/platforms/include/mach/irq-c645x.h
new file mode 100644
index 0000000..af027ea
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/irq-c645x.h
@@ -0,0 +1,131 @@
+/*
+ * arch/c6x/platforms/include/mach/irq-c645x.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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 __MACH_IRQ_C645X_H
+#define __MACH_IRQ_C645X_H
+
+/*
+ * C645x peripheral interrupt sources
+ */
+#define IRQ_EVT0 0 /* combined events */
+#define IRQ_EVT1 1
+#define IRQ_EVT2 2
+#define IRQ_EVT3 3
+#define IRQ_EMUDTDMA 9 /* emulator events */
+#define IRQ_EMURTDXRX 11
+#define IRQ_EMURTDXTX 12
+#define IRQ_IDMAINT0 13 /* IDMA channel 0 event */
+#define IRQ_IDMAINT1 14 /* IDMA channel 1 event */
+#define IRQ_DSPINT 15 /* HPI/PCI-to-DSP event */
+#define IRQ_I2CINT 16 /* I2C event */
+#define IRQ_EMACINT 17 /* EMAC event */
+#define IRQ_AEASYNCERR 18 /* EMIFA error event */
+#define IRQ_RIOINT0 20 /* RapidIO events */
+#define IRQ_RIOINT1 21
+#if defined(CONFIG_SOC_TMS320C6455)
+#define IRQ_RIOINT4 22
+#endif
+#if defined(CONFIG_SOC_TMS320C6457)
+#define IRQ_RIOINT2 23
+#define IRQ_RIOINT3 24
+#endif
+#define IRQ_EDMA3CCGINT 24 /* EDMA channel completion event */
+#if defined(CONFIG_SOC_TMS320C6457)
+#define IRQ_EMACRXINT 25
+#define IRQ_EMACTXINT 26
+#define IRQ_EMACTHRES 27
+#define IRQ_RIOINT4 28
+#define IRQ_RIOINT5 28
+#define IRQ_RIOINT6 28
+#else
+#define IRQ_EMACRXINT IRQ_EMACINT
+#define IRQ_EMACTXINT IRQ_EMACINT
+#endif
+#define IRQ_VCP2INT 32 /* VCP2 error event */
+#if defined(CONFIG_SOC_TMS320C6455)
+#define IRQ_TCP2INT 33 /* TCP2 error event */
+#endif
+#if defined(CONFIG_SOC_TMS320C6457)
+#define IRQ_TCP2AINT 33 /* TCP2 error event */
+#define IRQ_TCP2BINT 34 /* TCP2 error event */
+#endif
+#define IRQ_UINT 36 /* UTOPIA event */
+#define IRQ_RINT0 40 /* McBSP event */
+#define IRQ_XINT0 41
+#define IRQ_RINT1 42
+#define IRQ_XINT1 43
+#define IRQ_GPIO_START 51
+#define IRQ_GPIO0 51 /* GPIO events */
+#define IRQ_GPIO1 52
+#define IRQ_GPIO2 53
+#define IRQ_GPIO3 54
+#define IRQ_GPIO4 55
+#define IRQ_GPIO5 56
+#define IRQ_GPIO6 57
+#define IRQ_GPIO7 58
+#define IRQ_GPIO8 59
+#define IRQ_GPIO9 60
+#define IRQ_GPIO10 61
+#define IRQ_GPIO11 62
+#define IRQ_GPIO12 63
+#define IRQ_GPIO13 64
+#define IRQ_GPIO14 65
+#define IRQ_GPIO15 66
+#define IRQ_TINT0 67 /* timer events */
+#define IRQ_TINTLO0 67
+#define IRQ_TINTHI0 68
+#define IRQ_TINT1 69
+#define IRQ_TINTLO1 69
+#define IRQ_TINTHI1 70
+#define IRQ_EDMA3CCINT0 71 /* EDMA events */
+#define IRQ_EDMA3CCINT1 72
+#define IRQ_EDMA3CCINT2 73
+#define IRQ_EDMA3CCINT3 74
+#define IRQ_EDMA3CCINT4 75
+#define IRQ_EDMA3CCINT5 76
+#define IRQ_EDMA3CCINT6 77
+#define IRQ_EDMA3CCINT7 78
+#define IRQ_EDMA3CCERRINT 79
+#define IRQ_EDMA3CCMPINT 80
+#define IRQ_EDMA3C0ERRINT 81
+#define IRQ_EDMA3C1ERRINT 82
+#define IRQ_EDMA3C2ERRINT 83
+#define IRQ_EDMA3C3ERRINT 84
+#if defined(CONFIG_SOC_TMS320C6457)
+#define IRQ_EDMA3CCAET 85
+#define IRQ_EDMA3C4ERRINT 86
+#define IRQ_EDMA3C5ERRINT 86
+#define IRQ_ETBOVFLINT 94
+#define IRQ_ETBUNFLINT 95
+#endif
+#define IRQ_INTERR 96 /* interrupt controller dropped CPU interrupt event */
+#define IRQ_EMCIDMAERR 97 /* EMC invalid IDMA parameters */
+#if defined(CONFIG_SOC_TMS320C6457)
+#define IRQ_EFIINTA 100
+#define IRQ_EFIINTB 101
+#define IRQ_L1PED1 113
+#define IRQ_L1ED1 116
+#define IRQ_L2ED1 117
+#define IRQ_PDCINT 118
+#endif
+#define IRQ_L1PCMPA 120 /* L1P CPU memory protection fault */
+#define IRQ_L1PDMPA 121 /* L1P DMA memory protection fault */
+#define IRQ_L1DCMPA 122 /* L1D CPU memory protection fault */
+#define IRQ_L1DDMPA 123 /* L1D DMA memory protection fault */
+#define IRQ_L2CMPA 124 /* L2 CPU memory protection fault */
+#define IRQ_L2CDMPA 125 /* L2 DMA memory protection fault */
+#define IRQ_IDMACMPA 126 /* IDMA CPU memory protection fault */
+#define IRQ_IDMABUSERR 127 /* IDMA bus error fault */
+
+#define NR_SOC_IRQS 128
+
+#endif /* __MACH_IRQ_C645X_H */
diff --git a/arch/c6x/platforms/include/mach/irq-c6472.h b/arch/c6x/platforms/include/mach/irq-c6472.h
new file mode 100644
index 0000000..5c5522f
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/irq-c6472.h
@@ -0,0 +1,138 @@
+/*
+ * arch/c6x/platforms/include/mach/irq-c6472.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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 __MACH_IRQ_C6472_H
+#define __MACH_IRQ_C6472_H
+
+#define IRQ_EVT0 0 /* combined events */
+#define IRQ_EVT1 1
+#define IRQ_EVT2 2
+#define IRQ_EVT3 3
+#define IRQ_RIOINT 4 /* RapidIO individual interrupt */
+#define IRQ_EMACRXINT 5
+#define IRQ_EMACTXINT 6
+#define IRQ_EMACRXINT0 5
+#define IRQ_EMACTXINT0 6
+#define IRQ_EMACRXINT1 7
+#define IRQ_EMACTXINT1 8
+#define IRQ_EMUDTDMA 9 /* emulator events */
+#define IRQ_RESERVED 10 /* reserved */
+#define IRQ_EMURTDXRX 11
+#define IRQ_EMURTDXTX 12
+#define IRQ_IDMAINT0 13 /* IDMA channel 0 interrupt */
+#define IRQ_IDMAINT1 14 /* IDMA channel 1 interrupt */
+#define IRQ_EDMA3CCINT 15 /* EDMA3CC completion interrupt */
+#define IRQ_TINT 16 /* timer interrupts */
+#define IRQ_TINTLO 16
+#define IRQ_TINTHI 17
+#define IRQ_TINT6 18
+#define IRQ_TINTLO6 18
+#define IRQ_TINTHI6 19
+#define IRQ_TINT7 20
+#define IRQ_TINTLO7 20
+#define IRQ_TINTHI7 21
+#define IRQ_TINT8 22
+#define IRQ_TINTLO8 22
+#define IRQ_TINTHI8 23
+#define IRQ_TINT9 24
+#define IRQ_TINTLO9 24
+#define IRQ_TINTHI9 25
+#define IRQ_TINT10 26
+#define IRQ_TINTLO10 26
+#define IRQ_TINTHI10 27
+#define IRQ_TINT11 28
+#define IRQ_TINTLO11 28
+#define IRQ_TINTHI11 29
+#define IRQ_PRINT 30 /* UTOPIA-PDMA interrupts */
+#define IRQ_PXINT 31
+#define IRQ_RFSINT0 32 /* TSIP interrupts */
+#define IRQ_RSFINT0 33
+#define IRQ_XFSINT0 34
+#define IRQ_XSFINT0 35
+#define IRQ_RFSINT1 36
+#define IRQ_RSFINT1 37
+#define IRQ_XFSINT1 38
+#define IRQ_XSFINT1 39
+#define IRQ_RFSINT2 40
+#define IRQ_RSFINT2 41
+#define IRQ_XFSINT2 42
+#define IRQ_XSFINT2 43
+#define IRQ_RIOINT6 44 /* RapidIO common/error interrupts */
+#define IRQ_RIOINT7 45
+#define IRQ_ERRINT0 50 /* TSIP0 error interrupt */
+#define IRQ_ERRINT1 52
+#define IRQ_ERRINT2 54
+#define IRQ_UINT 56 /* UTOPIA interrupt */
+#define IRQ_EDMA3CCERR 57 /* EDMA3 interrupts */
+#define IRQ_EDMA3CCMP 58
+#define IRQ_EDMA3TCERR0 59
+#define IRQ_EDMA3TCERR1 60
+#define IRQ_EDMA3TCERR2 61
+#define IRQ_EDMA3TCERR3 62
+#define IRQ_SMCMPINT 63 /* SMC interrupts */
+#define IRQ_SMCPEVT 64 /* SMC interrupts */
+#define IRQ_PSCINT 65 /* PSC interrupt */
+#define IRQ_EDMA3CCAETEVT 66 /* EDMA3 interrupts */
+#define IRQ_EDMA3CCINT6 67
+#define IRQ_EDMA3CCINT7 68
+#define IRQ_EDMA3CCGINT 69
+#define IRQ_EMACINT 70 /* EMAC interrupts */
+#define IRQ_EMACINT0 70
+#define IRQ_EMACINT1 71
+#define IRQ_I2CINT 72 /* I2C interrupt */
+
+/*
+ * An IRQ from one and only one of GPIO 0-5 gets routed to core 0-5.
+ * core0 gets IRQ_GPIO0, core1 gets IRQ_GPIO1, etc.
+ */
+#define IRQ_GPIO_START 73
+#define IRQ_GPIOINT 73
+#define IRQ_GPIO6 74
+#define IRQ_GPIO7 75
+#define IRQ_GPIO8 76
+#define IRQ_GPIO9 77
+#define IRQ_GPIO10 78
+#define IRQ_GPIO11 79
+#define IRQ_GPIO12 80
+#define IRQ_GPIO13 81
+#define IRQ_GPIO14 82
+#define IRQ_GPIO15 83
+#define IRQ_IPCLOCAL 84 /* inter DSP interrupt from IPCGR */
+#define IRQ_HPIINT 85 /* HPI interrupt */
+#define IRQ_CPUINT0 87
+#define IRQ_CPUINT1 88
+#define IRQ_CPUINT2 89
+#define IRQ_CPUINT3 90
+#define IRQ_CPUINT4 91
+#define IRQ_CPUINT5 92
+#define IRQ_L2PDWAKE 93 /* L2 wake interrupt */
+#define IRQ_INTERR 96 /* interrupt controller dropped CPU interrupt event */
+#define IRQ_EMCIDMAERR 97 /* EMC invalid IDMA parameters */
+#define IRQ_PBISTINT 98 /* PBIS interrupt */
+#define IRQ_EFINTA 100 /* EFI interrupt from side A */
+#define IRQ_EFINTB 101 /* EFI interrupt from side B */
+#define IRQ_PMCED 113 /* single bit error detected during DMA read */
+#define IRQ_UMCED1 116 /* corrected bit error detected */
+#define IRQ_UMCED2 117 /* uncorrected bit error detected */
+#define IRQ_PDCINT 118 /* PDC sleep interrupt */
+#define IRQ_L1PCMPA 120 /* L1P CPU memory protection fault */
+#define IRQ_L1PDMPA 121 /* L1P DMA memory protection fault */
+#define IRQ_L1DCMPA 122 /* L1D CPU memory protection fault */
+#define IRQ_L1DDMPA 123 /* L1D DMA memory protection fault */
+#define IRQ_L2CMPA 124 /* L2 CPU memory protection fault */
+#define IRQ_L2CDMPA 125 /* L2 DMA memory protection fault */
+#define IRQ_EMCCMPA 126 /* external CPU memory protection fault */
+#define IRQ_EMCBUSERR 127 /* bus error interrupt */
+
+#define NR_SOC_IRQS 128
+
+#endif /* __MACH_IRQ_C6472_H */
diff --git a/arch/c6x/platforms/include/mach/irq-c6474.h b/arch/c6x/platforms/include/mach/irq-c6474.h
new file mode 100644
index 0000000..3ede1f6
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/irq-c6474.h
@@ -0,0 +1,323 @@
+/*
+ * arch/c6x/platforms/include/mach/irq-c6474.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * 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 __MACH_IRQ_C6474_H
+#define __MACH_IRQ_C6474_H
+
+#define IRQ_EVT0 0 /* combined events */
+#define IRQ_EVT1 1
+#define IRQ_EVT2 2
+#define IRQ_EVT3 3
+#define IRQ_SEMINT 4 /* semaphore grant interrupt */
+#define IRQ_EMACINT 5 /* EMAC interrupts */
+#define IRQ_EMACRXINT 6
+#define IRQ_EMACTXINT 7
+#define IRQ_EMACTHRES 8
+#define IRQ_EMUDTDMA 9 /* emulator events */
+#define IRQ_RACINT 10 /* RAC interrupt */
+#define IRQ_EMURTDXRX 11
+#define IRQ_EMURTDXTX 12
+#define IRQ_IDMAINT0 13 /* IDMA channel 0 interrupt */
+#define IRQ_IDMAINT1 14 /* IDMA channel 1 interrupt */
+#define IRQ_FSEVT0 15 /* frame synchronization events */
+#define IRQ_FSEVT1 16
+#define IRQ_FSEVT2 17
+#define IRQ_FSEVT3 18
+#define IRQ_FSEVT4 19
+#define IRQ_FSEVT5 29
+#define IRQ_FSEVT6 21
+#define IRQ_FSEVT7 22
+#define IRQ_FSEVT8 23
+#define IRQ_FSEVT9 24
+#define IRQ_FSEVT10 25
+#define IRQ_FSEVT11 26
+#define IRQ_FSEVT12 27
+#define IRQ_FSEVT13 28
+#define IRQ_FSEVT14 29
+#define IRQ_FSEVT15 30
+#define IRQ_FSEVT16 31
+#define IRQ_FSEVT17 32
+#define IRQ_TINT0 33 /* timer interrupts */
+#define IRQ_TINTLO0 33
+#define IRQ_TINTHI0 34
+#define IRQ_TINT1 35
+#define IRQ_TINTLO1 35
+#define IRQ_TINTHI1 36
+#define IRQ_TINT2 37
+#define IRQ_TINTLO2 37
+#define IRQ_TINTHI2 38
+#define IRQ_TINT3 39
+#define IRQ_TINTLO3 39
+#define IRQ_TINTHI3 40
+#define IRQ_TINT4 41
+#define IRQ_TINTLO4 41
+#define IRQ_TINTHI4 42
+#define IRQ_TINT5 43
+#define IRQ_TINTLO5 43
+#define IRQ_TINTHI5 44
+#define IRQ_GPIO_START 45
+#define IRQ_GPIO0 45 /* GPIO events */
+#define IRQ_GPIO1 46
+#define IRQ_GPIO2 47
+#define IRQ_GPIO3 48
+#define IRQ_GPIO4 49
+#define IRQ_GPIO5 50
+#define IRQ_GPIO6 51
+#define IRQ_GPIO7 52
+#define IRQ_GPIO8 53
+#define IRQ_GPIO9 54
+#define IRQ_GPIO10 55
+#define IRQ_GPIO11 56
+#define IRQ_GPIO12 57
+#define IRQ_GPIO13 58
+#define IRQ_GPIO14 59
+#define IRQ_GPIO15 60
+#define IRQ_TPCCGINT 61 /* EDMA channel global completion interrupt */
+#define IRQ_TPCCINT0 62 /* TPCC completion interrupts */
+#define IRQ_TPCCINT1 63
+#define IRQ_TPCCINT2 64
+#define IRQ_TPCCINT3 65
+#define IRQ_TPCCINT4 66
+#define IRQ_TPCCINT5 67
+#define IRQ_TPCCINT6 68
+#define IRQ_TPCCINT7 69
+#define IRQ_RIOINT0 71 /* RapidIO interrupts */
+#define IRQ_RIOINT1 72
+#define IRQ_AIFEVT0 73 /* error/alarm events*/
+#define IRQ_AIFEVT1 74
+#define IRQ_IPCLOCAL 76 /* inter DSP interrupt from IPCGR */
+
+#define CIC_MAPBASE 80 /* start of system events from CIC */
+#define CIC_MAPLEN 14 /* number of events from CIC */
+
+#define IRQ_CICEVT0 80
+#define IRQ_CICEVT1 81
+#define IRQ_CICEVT2 82
+#define IRQ_CICEVT3 83
+#define IRQ_CICEVT4 84
+#define IRQ_CICEVT5 85
+#define IRQ_CICEVT6 86
+#define IRQ_CICEVT7 87
+#define IRQ_CICEVT8 88
+#define IRQ_CICEVT9 89
+#define IRQ_CICEVT10 90
+#define IRQ_CICEVT11 91
+#define IRQ_CICEVT12 92
+#define IRQ_CICEVT13 93
+
+#define IRQ_INTERR 96 /* irq controller dropped CPU interrupt event */
+#define IRQ_EMCIDMAERR 97 /* EMC invalid IDMA parameters */
+#define IRQ_EFINTA 100 /* EFI interrupt from side A */
+#define IRQ_EFINTB 101 /* EFI interrupt from side B */
+#define IRQ_PMCED 113 /* single bit error detected during DMA read */
+#define IRQ_UMCED1 116 /* corrected bit error detected */
+#define IRQ_UMCED2 117 /* uncorrected bit error detected */
+#define IRQ_PDCINT 118 /* PDC sleep interrupt */
+#define IRQ_SYSCMPA 119 /* CPU memory protection fault */
+#define IRQ_L1PCMPA 120 /* L1P CPU memory protection fault */
+#define IRQ_L1PDMPA 121 /* L1P DMA memory protection fault */
+#define IRQ_L1DCMPA 122 /* L1D CPU memory protection fault */
+#define IRQ_L1DDMPA 123 /* L1D DMA memory protection fault */
+#define IRQ_L2CMPA 124 /* L2 CPU memory protection fault */
+#define IRQ_L2CDMPA 125 /* L2 DMA memory protection fault */
+#define IRQ_EMCCMPA 126 /* external CPU memory protection fault */
+#define IRQ_EMCBUSERR 127 /* bus error interrupt */
+
+/*
+ * C6x Chip Interrupt Controller (CIC) events
+ */
+#define IRQ_CIC_START 128
+#define IRQ_I2CINT (IRQ_CIC_START + 4) /* I2C event */
+#define IRQ_FSERR1 (IRQ_CIC_START + 5) /* error/alarm interrupts */
+#define IRQ_RIOINT7 (IRQ_CIC_START + 6)
+#define IRQ_FSERR2 (IRQ_CIC_START + 7)
+#define IRQ_VCPINT (IRQ_CIC_START + 8)
+#define IRQ_TCPINT (IRQ_CIC_START + 9)
+#define IRQ_RINT0 (IRQ_CIC_START + 10) /* McBSP event */
+#define IRQ_XINT0 (IRQ_CIC_START + 11)
+#define IRQ_RINT1 (IRQ_CIC_START + 12)
+#define IRQ_XINT1 (IRQ_CIC_START + 13)
+#define IRQ_REVT0 (IRQ_CIC_START + 14)
+#define IRQ_XEVT0 (IRQ_CIC_START + 15)
+#define IRQ_REVT1 (IRQ_CIC_START + 16)
+#define IRQ_XEVT1 (IRQ_CIC_START + 17)
+#define IRQ_IREVT1 (IRQ_CIC_START + 18) /* I2C EDMA events */
+#define IRQ_IXEVT1 (IRQ_CIC_START + 19)
+#define IRQ_FSEVT18 (IRQ_CIC_START + 20) /* frame synchronization events */
+#define IRQ_FSEVT19 (IRQ_CIC_START + 21)
+#define IRQ_FSEVT20 (IRQ_CIC_START + 22)
+#define IRQ_FSEVT21 (IRQ_CIC_START + 23)
+#define IRQ_FSEVT22 (IRQ_CIC_START + 24)
+#define IRQ_FSEVT23 (IRQ_CIC_START + 25)
+#define IRQ_FSEVT24 (IRQ_CIC_START + 26)
+#define IRQ_FSEVT25 (IRQ_CIC_START + 27)
+#define IRQ_FSEVT26 (IRQ_CIC_START + 28)
+#define IRQ_FSEVT27 (IRQ_CIC_START + 29)
+#define IRQ_FSEVT28 (IRQ_CIC_START + 30)
+#define IRQ_FSEVT29 (IRQ_CIC_START + 31)
+#define IRQ_VCPREVT (IRQ_CIC_START + 32) /* VCP events */
+#define IRQ_VCPXEVT (IRQ_CIC_START + 33)
+#define IRQ_TCPREVT (IRQ_CIC_START + 34) /* TCP events */
+#define IRQ_TCPXEVT (IRQ_CIC_START + 35)
+#define IRQ_TPCCERRINT (IRQ_CIC_START + 36) /* TPCC error interrupt */
+#define IRQ_TPCCMPINT (IRQ_CIC_START + 37) /* TPCSS memory protection interrupt */
+#define IRQ_TPTCERRINT0 (IRQ_CIC_START + 38) /* TPTC error interrupts */
+#define IRQ_TPTCERRINT1 (IRQ_CIC_START + 39)
+#define IRQ_TPTCERRINT2 (IRQ_CIC_START + 40)
+#define IRQ_TPTCERRINT3 (IRQ_CIC_START + 41)
+#define IRQ_TPTCERRINT4 (IRQ_CIC_START + 42)
+#define IRQ_TPTCERRINT5 (IRQ_CIC_START + 43)
+#define IRQ_TPTCAETEVT (IRQ_CIC_START + 44) /* TPTC AET event */
+#define IRQ_AIFEVT2 (IRQ_CIC_START + 45) /* AIF CPU interrupts */
+#define IRQ_AIFEVT3 (IRQ_CIC_START + 46)
+#define IRQ_AIFPSEVT0 (IRQ_CIC_START + 47) /* packet switched transfer events */
+#define IRQ_AIFPSEVT1 (IRQ_CIC_START + 48)
+#define IRQ_AIFPSEVT2 (IRQ_CIC_START + 49)
+#define IRQ_AIFPSEVT3 (IRQ_CIC_START + 50)
+#define IRQ_AIFPSEVT4 (IRQ_CIC_START + 51)
+#define IRQ_AIFPSEVT5 (IRQ_CIC_START + 52)
+#define IRQ_AIFPSEVT6 (IRQ_CIC_START + 53)
+#define IRQ_AIFBUFEVT (IRQ_CIC_START + 54)
+#define IRQ_RACDEVENT0 (IRQ_CIC_START + 56) /* debug events */
+#define IRQ_RACDEVENT1 (IRQ_CIC_START + 57)
+#define IRQ_SEMERR (IRQ_CIC_START + 58)
+
+#define NR_CIC_IRQS 64
+
+#define NR_SOC_IRQS (IRQ_CIC_START + NR_CIC_IRQS)
+
+/*
+ * C6x Chip Interrupt Controller (CIC) register layout
+ */
+#define CIC_REG_BASE(corenum) (0x02880000 + (0x100 * (corenum)))
+
+#define CIC_EVTFLAG(n) __SYSREGA(CIC_REG_BASE(n) + 0x00, uint32_t)
+#define CIC_EVTSET(n) __SYSREGA(CIC_REG_BASE(n) + 0x10, uint32_t)
+#define CIC_EVTCLR(n) __SYSREGA(CIC_REG_BASE(n) + 0x20, uint32_t)
+#define CIC_EVTMASK(n) __SYSREGA(CIC_REG_BASE(n) + 0x30, uint32_t)
+#define CIC_MEVTFLAG(n) __SYSREGA(CIC_REG_BASE(n) + 0x40, uint32_t)
+#define CIC_MUX(n) __SYSREGA(CIC_REG_BASE(n) + 0x50, uint32_t)
+
+#define CIC0_EVTFLAG __SYSREGA(CIC_REG_BASE(0) + 0x00, uint32_t)
+#define CIC0_EVTSET __SYSREGA(CIC_REG_BASE(0) + 0x10, uint32_t)
+#define CIC0_EVTCLR __SYSREGA(CIC_REG_BASE(0) + 0x20, uint32_t)
+#define CIC0_EVTMASK __SYSREGA(CIC_REG_BASE(0) + 0x30, uint32_t)
+#define CIC0_MEVTFLAG __SYSREGA(CIC_REG_BASE(0) + 0x40, uint32_t)
+#define CIC0_MUX __SYSREGA(CIC_REG_BASE(0) + 0x50, uint32_t)
+
+#define CIC1_EVTFLAG __SYSREGA(CIC_REG_BASE(1) + 0x00, uint32_t)
+#define CIC1_EVTSET __SYSREGA(CIC_REG_BASE(1) + 0x10, uint32_t)
+#define CIC1_EVTCLR __SYSREGA(CIC_REG_BASE(1) + 0x20, uint32_t)
+#define CIC1_EVTMASK __SYSREGA(CIC_REG_BASE(1) + 0x30, uint32_t)
+#define CIC1_MEVTFLAG __SYSREGA(CIC_REG_BASE(1) + 0x40, uint32_t)
+#define CIC1_MUX __SYSREGA(CIC_REG_BASE(1) + 0x50, uint32_t)
+
+#define CIC2_EVTFLAG __SYSREGA(CIC_REG_BASE(2) + 0x00, uint32_t)
+#define CIC2_EVTSET __SYSREGA(CIC_REG_BASE(2) + 0x10, uint32_t)
+#define CIC2_EVTCLR __SYSREGA(CIC_REG_BASE(2) + 0x20, uint32_t)
+#define CIC2_EVTMASK __SYSREGA(CIC_REG_BASE(2) + 0x30, uint32_t)
+#define CIC2_MEVTFLAG __SYSREGA(CIC_REG_BASE(2) + 0x40, uint32_t)
+#define CIC2_MUX __SYSREGA(CIC_REG_BASE(2) + 0x50, uint32_t)
+
+#define CIC3_EVTFLAG __SYSREGA(CIC_REG_BASE(3) + 0x00, uint32_t)
+#define CIC3_EVTSET __SYSREGA(CIC_REG_BASE(3) + 0x10, uint32_t)
+#define CIC3_EVTCLR __SYSREGA(CIC_REG_BASE(3) + 0x20, uint32_t)
+#define CIC3_EVTMASK __SYSREGA(CIC_REG_BASE(3) + 0x30, uint32_t)
+#define CIC3_MEVTFLAG __SYSREGA(CIC_REG_BASE(3) + 0x40, uint32_t)
+#define CIC3_MUX __SYSREGA(CIC_REG_BASE(3) + 0x50, uint32_t)
+
+/*
+ * CIC output events (16)
+ */
+#define CIC0 0
+#define CIC1 1
+#define CIC2 2
+#define CIC3 3
+#define CIC4 4
+#define CIC5 5
+#define CIC6 6
+#define CIC7 7
+#define CIC8 8
+#define CIC9 9
+#define CIC10 10
+#define CIC11 11
+#define CIC12 12
+#define CIC13 13
+#define CIC14 14
+#define CIC15 15
+
+/*
+ * CIC events for CIC3 (CIC TPCC)
+ */
+#define CIC_TPCC 3 /* CIC TPPC is CIC3 */
+
+#define CIC_TPCC_EVT0 0 /* combined events */
+#define CIC_TPCC_EVT1 1
+#define CIC_TPCC_FSEVT0 2 /* frame synchronization events */
+#define CIC_TPCC_FSEVT1 3
+#define CIC_TPCC_FSEVT2 4
+#define CIC_TPCC_FSEVT3 5
+#define CIC_TPCC_FSEVT14 6
+#define CIC_TPCC_FSEVT15 7
+#define CIC_TPCC_FSEVT16 8
+#define CIC_TPCC_FSEVT17 9
+#define CIC_TPCC_FSEVT18 10
+#define CIC_TPCC_FSEVT19 11
+#define CIC_TPCC_FSEVT20 12
+#define CIC_TPCC_FSEVT21 13
+#define CIC_TPCC_FSEVT22 14
+#define CIC_TPCC_FSEVT23 15
+#define CIC_TPCC_FSEVT24 16
+#define CIC_TPCC_FSEVT25 17
+#define CIC_TPCC_FSEVT26 18
+#define CIC_TPCC_FSEVT27 19
+#define CIC_TPCC_FSEVT28 20
+#define CIC_TPCC_RIOINT0 21
+#define CIC_TPCC_RIOINT1 22
+#define CIC_TPCC_RIOINT2 23
+#define CIC_TPCC_RIOINT3 24
+#define CIC_TPCC_RIOINT4 25
+#define CIC_TPCC_RIOINT5 26
+#define CIC_TPCC_RIOINT7 27
+#define CIC_TPCC_MACINT0 28
+#define CIC_TPCC_MACRINT0 29
+#define CIC_TPCC_MACTINT0 30
+#define CIC_TPCC_MACINT1 31
+#define CIC_TPCC_MACRINT1 32
+#define CIC_TPCC_MACTINT1 33
+#define CIC_TPCC_MACINT2 34
+#define CIC_TPCC_MACRINT2 35
+#define CIC_TPCC_MACTINT2 36
+#define CIC_TPCC_SEMERR0 37
+#define CIC_TPCC_SEMERR1 38
+#define CIC_TPCC_SEMERR2 39
+#define CIC_TPCC_TINT3L 43
+#define CIC_TPCC_TINT3H 44
+#define CIC_TPCC_TINT4L 45
+#define CIC_TPCC_TINT4H 46
+#define CIC_TPCC_TINT5L 47
+#define CIC_TPCC_TINT5H 48
+#define CIC_TPCC_AIFTEVT0 49
+#define CIC_TPCC_AIFTEVT1 50
+#define CIC_TPCC_GPINT0 53
+#define CIC_TPCC_GPINT1 54
+#define CIC_TPCC_GPINT2 55
+#define CIC_TPCC_GPINT3 56
+#define CIC_TPCC_GPINT4 57
+#define CIC_TPCC_CIC0E14 58
+#define CIC_TPCC_CIC0E15 59
+#define CIC_TPCC_CIC1E14 60
+#define CIC_TPCC_CIC1E15 61
+#define CIC_TPCC_CIC2E14 62
+#define CIC_TPCC_CIC2E15 63
+
+#endif /* __MACH_IRQ_C6474_H */
diff --git a/arch/c6x/platforms/include/mach/irq.h b/arch/c6x/platforms/include/mach/irq.h
new file mode 100644
index 0000000..1d9b78c
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/irq.h
@@ -0,0 +1,52 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/irq.h
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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 __MACH_C6X_IRQ_H
+#define __MACH_C6X_IRQ_H
+
+#if defined(CONFIG_SOC_TMS320C6455) || defined(CONFIG_SOC_TMS320C6457)
+#include <mach/irq-c645x.h>
+#elif defined(CONFIG_SOC_TMS320C6472)
+#include <mach/irq-c6472.h>
+#elif defined(CONFIG_SOC_TMS320C6474)
+#include <mach/irq-c6474.h>
+#else
+#error "No machine IRQ definitions"
+#endif
+
+#ifdef __KERNEL__
+
+#define IC_EVTFLAG __SYSREGA(0x01800000, uint32_t)
+#define IC_EVTSET __SYSREGA(0x01800020, uint32_t)
+#define IC_EVTCLR __SYSREGA(0x01800040, uint32_t)
+#define IC_EVTMASK __SYSREGA(0x01800080, uint32_t)
+#define IC_MEVTFLAG __SYSREGA(0x018000a0, uint32_t)
+#define IC_EXPMASK __SYSREGA(0x018000c0, uint32_t)
+#define IC_MEXPMASK __SYSREGA(0x018000e0, uint32_t)
+#define IC_INTMUX __SYSREGA(0x01800100, uint32_t)
+#define IC_AEGMUX __SYSREGA(0x01800140, uint32_t)
+#define IC_INTXSTAT __SYSREG(0x01800180, uint32_t)
+#define IC_INTXCLR __SYSREG(0x01800184, uint32_t)
+#define IC_INTDMASK __SYSREG(0x01800188, uint32_t)
+#define IC_EVTASRT __SYSREG(0x018001c0, uint32_t)
+
+/*
+ * EVTASRT bits
+ */
+#define IC_B_EVTPULSE4 (1 << 4)
+
+#define assert_event(evt) (IC_EVTASRT = (evt))
+
+#define NR_BOARD_IRQS 0 /* Not used */
+
+#endif /* __KERNEL__ */
+#endif /* __MACH_C6X_IRQ_H */
diff --git a/arch/c6x/platforms/include/mach/pll.h b/arch/c6x/platforms/include/mach/pll.h
new file mode 100644
index 0000000..4d90775
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/pll.h
@@ -0,0 +1,134 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/pll.h
+ *
+ * PLL definitions for Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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 __MACH_C6X_PLL_H
+#define __MACH_C6X_PLL_H
+
+#if defined(CONFIG_SOC_TMS320C6455)
+#define ARCH_PLL1_BASE 0x029A0000
+#define ARCH_PLL2_BASE 0x029C0000
+
+/*
+ * Datasheet recommends a wait for 4 CLKIN cycles to ensure that the
+ * PLL has switched to bypass mode. Delay of 1us ensures we are good for
+ * all > 4MHz CLKIN inputs. Typically the input is ~25MHz.
+ * Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+
+#define PLL_RESET_TIME 128
+#define PLL_LOCK_TIME 2000
+
+#elif defined(CONFIG_SOC_TMS320C6457)
+#define ARCH_PLL1_BASE 0x029A0000
+
+/*
+ * Datasheet recommends a wait for 4 CLKIN cycles to ensure that the
+ * PLL has switched to bypass mode. Delay of 1us ensures we are good for
+ * all > 4MHz CLKIN inputs. Typically the input is ~25MHz.
+ * Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+
+#define PLL_RESET_TIME 1000
+#define PLL_LOCK_TIME 2000
+
+#elif defined(CONFIG_SOC_TMS320C6472)
+#define ARCH_PLL1_BASE 0x029A0000
+#define ARCH_PLL2_BASE 0x029C0000
+#define ARCH_PLL3_BASE 0x029C0400
+
+/*
+ * Datasheet recommends a wait for 4 CLKIN cycles to ensure that the
+ * PLL has switched to bypass mode. Delay of 1us ensures we are good for
+ * all > 4MHz CLKIN inputs. Typically the input is ~25MHz.
+ * Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+
+#define PLL_RESET_TIME 256
+#define PLL_LOCK_TIME 2000
+
+#elif defined(CONFIG_SOC_TMS320C6474)
+#define ARCH_PLL1_BASE 0x029A0000
+
+/*
+ * Datasheet recommends a wait for 4 CLKIN cycles to ensure that the
+ * PLL has switched to bypass mode. Delay of 1us ensures we are good for
+ * all > 4MHz CLKIN inputs. Typically the input is ~25MHz.
+ * Units are micro seconds.
+ */
+#define PLL_BYPASS_TIME 1
+
+#define PLL_RESET_TIME 256
+#define PLL_LOCK_TIME 2000
+
+#endif
+
+/* PLL/Reset register offsets */
+#define PLLCTL 0x100
+#define PLLM 0x110
+#define PREDIV 0x114
+#define PLLDIV1 0x118
+#define PLLDIV2 0x11c
+#define PLLDIV3 0x120
+#define PLLPOSTDIV 0x128
+#define PLLCMD 0x138
+#define PLLSTAT 0x13c
+#define PLLALNCTL 0x140
+#define PLLDCHANGE 0x144
+#define PLLCKEN 0x148
+#define PLLCKSTAT 0x14c
+#define PLLSYSTAT 0x150
+#define PLLDIV4 0x160
+#define PLLDIV5 0x164
+#define PLLDIV6 0x168
+#define PLLDIV7 0x16c
+#define PLLDIV8 0x170
+#define PLLDIV9 0x174
+#define PLLDIV10 0x178
+#define PLLDIV11 0x17c
+#define PLLDIV12 0x180
+#define PLLDIV13 0x184
+#define PLLDIV14 0x188
+#define PLLDIV15 0x18c
+#define PLLDIV16 0x190
+
+/* PLLM register bits */
+#define PLLM_PLLM_MASK 0xff
+#define PLLM_VAL(x) ((x) - 1)
+
+/* PREDIV register bits */
+#define PLLPREDIV_EN BIT(15)
+#define PLLPREDIV_VAL(x) ((x) - 1)
+
+/* PLLCTL register bits */
+#define PLLCTL_PLLEN BIT(0)
+#define PLLCTL_PLLPWRDN BIT(1)
+#define PLLCTL_PLLRST BIT(3)
+#define PLLCTL_PLLDIS BIT(4)
+#define PLLCTL_PLLENSRC BIT(5)
+#define PLLCTL_CLKMODE BIT(8)
+
+/* PLLCMD register bits */
+#define PLLCMD_GOSTAT BIT(0)
+
+/* PLLSTAT register bits */
+#define PLLSTAT_GOSTAT BIT(0)
+
+/* PLLDIV register bits */
+#define PLLDIV_EN BIT(15)
+#define PLLDIV_RATIO_MASK 0x1f
+#define PLLDIV_RATIO(x) ((x) - 1)
+
+#endif /* __MACH_C6X_PLL_H */
diff --git a/arch/c6x/platforms/include/mach/timer.h b/arch/c6x/platforms/include/mach/timer.h
new file mode 100644
index 0000000..634b321
--- /dev/null
+++ b/arch/c6x/platforms/include/mach/timer.h
@@ -0,0 +1,104 @@
+/*
+ * linux/arch/c6x/platforms/include/mach/timer.h
+ *
+ * Timer definitions for Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Author: Mark Salter <[email protected]>
+ *
+ * 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 __MACH_C6X_TIMER_H
+#define __MACH_C6X_TIMER_H
+
+/*
+ * Timers register base
+ */
+#if defined(CONFIG_SOC_TMS320C6455) || defined(CONFIG_SOC_TMS320C6457)
+#define TIMER_BASE_ADDR 0x02940000
+#define TIMER_CHAN_MULT 0x40000
+#elif defined(CONFIG_SOC_TMS320C6472)
+#define TIMER_BASE_ADDR 0x025e0000
+#define TIMER_CHAN_MULT 0x10000
+#elif defined(CONFIG_SOC_TMS320C6474)
+#define TIMER_BASE_ADDR 0x02910000
+#define TIMER_CHAN_MULT 0x10000
+
+#define TIMER_TINPSEL __SYSREG(0x02900000, unsigned int)
+#define TIMER_TOUTPSEL __SYSREG(0x02900004, unsigned int)
+#define TIMER_WDRSTSEL __SYSREG(0x02900008, unsigned int)
+#else
+#error "no timer base defined"
+#endif
+
+/*
+ * Timers management
+ */
+#define TIMER_BASE(chan) (TIMER_BASE_ADDR + \
+ ((chan) * TIMER_CHAN_MULT))
+#define TIMER_EMUMGTCLKSPD_REG(chan) (TIMER_BASE(chan) + 0x04)
+#define TIMER_CNTLO_REG(chan) (TIMER_BASE(chan) + 0x10)
+#define TIMER_CNTHI_REG(chan) (TIMER_BASE(chan) + 0x14)
+#define TIMER_PRDLO_REG(chan) (TIMER_BASE(chan) + 0x18)
+#define TIMER_PRDHI_REG(chan) (TIMER_BASE(chan) + 0x1c)
+#define TIMER_TCR_REG(chan) (TIMER_BASE(chan) + 0x20)
+#define TIMER_TGCR_REG(chan) (TIMER_BASE(chan) + 0x24)
+#define TIMER_WDTCR_REG(chan) (TIMER_BASE(chan) + 0x28)
+
+#define TIMER_B_TCR_TSTATLO 0x001
+#define TIMER_B_TCR_INVOUTPLO 0x002
+#define TIMER_B_TCR_INVINPLO 0x004
+#define TIMER_B_TCR_CPLO 0x008
+#define TIMER_B_TCR_ENAMODELO_ONCE 0x040
+#define TIMER_B_TCR_ENAMODELO_CONT 0x080
+#define TIMER_B_TCR_ENAMODELO_MASK 0x0c0
+#define TIMER_B_TCR_PWIDLO_MASK 0x030
+#define TIMER_B_TCR_CLKSRCLO 0x100
+#define TIMER_B_TCR_TIENLO 0x200
+#define TIMER_B_TCR_TSTATHI (0x001 << 16)
+#define TIMER_B_TCR_INVOUTPHI (0x002 << 16)
+#define TIMER_B_TCR_CPHI (0x008 << 16)
+#define TIMER_B_TCR_PWIDHI_MASK (0x030 << 16)
+#define TIMER_B_TCR_ENAMODEHI_ONCE (0x040 << 16)
+#define TIMER_B_TCR_ENAMODEHI_CONT (0x080 << 16)
+#define TIMER_B_TCR_ENAMODEHI_MASK (0x0c0 << 16)
+
+#define TIMER_B_TGCR_TIMLORS 0x001
+#define TIMER_B_TGCR_TIMHIRS 0x002
+#define TIMER_B_TGCR_TIMMODE_UD32 0x004
+#define TIMER_B_TGCR_TIMMODE_WDT64 0x008
+#define TIMER_B_TGCR_TIMMODE_CD32 0x00c
+#define TIMER_B_TGCR_TIMMODE_MASK 0x00c
+#define TIMER_B_TGCR_PSCHI_MASK (0x00f << 8)
+#define TIMER_B_TGCR_TDDRHI_MASK (0x00f << 12)
+
+#define TIMER_0 0
+#define TIMER_1 1
+
+#if defined(CONFIG_SOC_TMS320C6472) || defined(CONFIG_SOC_TMS320C6474)
+#define TIMER_2 2
+#define TIMER_3 3
+#define TIMER_4 4
+#define TIMER_5 5
+#define TIMER_6 6
+#define TIMER_7 7
+#define TIMER_8 8
+#define TIMER_9 9
+#define TIMER_10 10
+#define TIMER_11 11
+#endif /* defined(CONFIG_SOC_TMS320C6472) || defined(CONFIG_SOC_TMS320C6474) */
+
+/*
+ * Timer clocks are divided down from the CPU clock
+ * The divisor is in the EMUMGTCLKSPD register
+ */
+#define TIMER_DIVISOR(t) \
+ ((TIMER_REG(TIMER_EMUMGTCLKSPD_REG((t))) & (0xf << 16)) >> 16)
+
+#define timer_period(f, d) (((f) * 1000000) / ((d) * HZ))
+#define ticks2usecs(f, d, x) (((x) * (d)) / (f))
+
+#endif
diff --git a/arch/c6x/platforms/phy.c b/arch/c6x/platforms/phy.c
new file mode 100644
index 0000000..f15e606
--- /dev/null
+++ b/arch/c6x/platforms/phy.c
@@ -0,0 +1,141 @@
+/*
+ * linux/arch/c6x/drivers/phy.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2007, 2009, 2010 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+
+#include <linux/kernel.h>
+#include <linux/delay.h>
+#include <linux/types.h>
+
+#include <asm/setup.h>
+#include <asm/io.h>
+#include <asm/gmdio.h>
+#include <asm/sgmii.h>
+
+static int phy_init(void)
+{
+#ifdef CONFIG_ARCH_BOARD_EVM6472
+
+ mdio_set_reg(MDIO_CONTROL, 0x4000001f); /* enable MII interface */
+
+ __delay(145844);
+
+ /* Port 0 */
+ mdio_phy_write(27, 0x18, 0x848b); /* set RGMII to copper mode */
+ mdio_phy_wait();
+
+ mdio_phy_write(20, 0x18, 0xce0); /* Rx-clock delayed */
+ mdio_phy_wait();
+
+ mdio_phy_write(24, 0x18, 0x4101); /* leds */
+ mdio_phy_wait();
+
+ mdio_phy_write(0, 0x18, 0x9140); /* soft-reset */
+ mdio_phy_wait();
+
+ __delay(145844);
+
+ /* Port 1 */
+ mdio_phy_write(27, 0x19, 0x848b); /* set RGMII to copper mode */
+ mdio_phy_wait();
+
+ mdio_phy_write(20, 0x19, 0xce0); /* Rx-clock delayed */
+ mdio_phy_wait();
+
+ mdio_phy_write(24, 0x19, 0x4101); /* leds */
+ mdio_phy_wait();
+
+ mdio_phy_write(0, 0x19, 0x9140); /* soft-reset */
+ mdio_phy_wait();
+
+ __delay(145844);
+
+#else /* !CONFIG_ARCH_BOARD_EVM6472 */
+
+ mdio_set_reg(MDIO_CONTROL, 0x4004001f); /* enable MII interface */
+
+ __delay(145844);
+
+ mdio_phy_write(4, 27, 0x81); /* turn PPU off to make copper PHY visible at SMI address 0x01 */
+ mdio_phy_wait();
+
+ __delay(8763);
+
+ mdio_phy_write(26, 0xe, 0x47); /* set PHY port 6 SERDES to 0.7V swing */
+ mdio_phy_wait();
+
+#ifdef CONFIG_ARCH_BOARD_EVM6474
+ mdio_phy_write(26, 0xd, 0x47); /* set PHY port 5 SERDES to 0.7V swing */
+ mdio_phy_wait();
+#endif
+
+ mdio_phy_write(0, 0xe, 0x8140); /* configure PHY port 6 SERDES --> DSP 1 at 1000mpbs, full duplex */
+ mdio_phy_wait();
+
+#ifdef CONFIG_ARCH_BOARD_EVM6474
+ mdio_phy_write(0, 0xd, 0x8140); /* configure PHY port 5 SERDES --> DSP 2 at 1000mbps, full duplex */
+ mdio_phy_wait();
+
+ mdio_phy_write(1, 0x15, 0x43e); /* force internal switch --> port 5 SERDES to 1000MPBS, full Duplex */
+ mdio_phy_wait();
+#endif
+
+ mdio_phy_write(1, 0x16, 0x43e); /* force internal switch --> port 6 SERDES to 1000MBPS, full Duplex */
+ mdio_phy_wait();
+
+#endif /* !CONFIG_ARCH_BOARD_EVM6472 */
+
+#if 0 /* Use autoneg at PHY level */
+
+ /* force 1000 or 100mps at copper PHY, disable auto-negotiate */
+ mdio_phy_write(0, 1, 0xa100); /* 0xa100 = 100mbps, 0x8140 = 1000mbps */
+ mdio_phy_wait();
+
+ /* wait for link establishment (~5 sec) */
+ {
+ int i;
+ for (i = 0; i < 5000; i++)
+ udelay(1000); /* 1ms */
+ }
+#endif
+ return 0;
+}
+
+static int evm_phy_init(void)
+{
+#if !defined(CONFIG_ARCH_BOARD_EVM6472)
+ struct sgmii_config_s sgmiic;
+
+ /* SGMII setup */
+ sgmii_reset();
+
+ sgmiic.master = 1;
+ sgmiic.loopback = 0;
+ sgmiic.autoneg = 0;
+ sgmiic.txconfig = 0x00000e23;
+ sgmiic.rxconfig = 0x00081023; /* programming serdes to be in master mode */
+ sgmiic.auxconfig = 0x0000000b; /* PLL multiplier */
+
+#ifdef CONFIG_ARCH_BOARD_EVM6474
+ /* EVMC6474 board is wired up with TX differential +/- swapped. */
+ sgmiic.txconfig |= 0x80;
+#endif /* CONFIG_ARCH_BOARD_EVM6474 */
+
+ sgmii_config(&sgmiic);
+
+#endif /* !defined(CONFIG_ARCH_BOARD_EVM6472) */
+
+ phy_init();
+
+ return 0;
+}
+
+arch_initcall(evm_phy_init);
diff --git a/arch/c6x/platforms/platform-c64xx.c b/arch/c6x/platforms/platform-c64xx.c
new file mode 100644
index 0000000..28d9244
--- /dev/null
+++ b/arch/c6x/platforms/platform-c64xx.c
@@ -0,0 +1,439 @@
+/*
+ * linux/arch/c6x/platforms/platform-c64xx.c
+ *
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2007, 2009, 2010, 2011 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ * Updated: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <linux/fs.h>
+#include <linux/genhd.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/delay.h>
+#include <linux/ioport.h>
+#include <linux/init.h>
+#include <linux/kernel_stat.h>
+#include <linux/types.h>
+#include <linux/ioport.h>
+#include <linux/platform_device.h>
+#include <linux/mtd/mtd.h>
+#include <linux/mtd/partitions.h>
+#include <linux/mtd/plat-ram.h>
+#include <linux/mtd/physmap.h>
+
+#include <asm/pll.h>
+#include <asm/timer.h>
+#include <asm/setup.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+
+#include <mach/dscr.h>
+#include <mach/board.h>
+#include <mach/gemac.h>
+
+/*
+ * Resources present on the SoC
+ */
+static struct resource c6x_soc_res = {
+ .name = "C64X+ SOC peripherals",
+#if defined(CONFIG_SOC_TMS320C6472) || defined(CONFIG_SOC_TMS320C6474)
+ .start = 0x01800000, .end = 0x02f60000,
+#elif defined(CONFIG_SOC_TMS320C6455) || defined(CONFIG_SOC_TMS320C6457)
+ .start = 0x01800000, .end = 0x2cffffff,
+#else
+#error "No SoC peripheral address space defined"
+#endif
+};
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+
+#ifdef CONFIG_MTD_PARTITIONS
+static const char *part_probe_types[] = { "cmdlinepart", NULL };
+#endif
+
+static struct platdata_mtd_ram c6x_plat_data = {
+ .mapname = "DRAM",
+#ifdef CONFIG_MTD_PARTITIONS
+ .probes = (const char **) part_probe_types,
+#endif
+ .bankwidth = 4,
+};
+
+static struct resource c6x_platram_resource = {
+ .start = 0,
+ .end = 0,
+ .flags = IORESOURCE_MEM,
+};
+
+static struct platform_device c6x_platram_device = {
+ .name = "mtd-ram",
+ .id = 8,
+ .dev = {
+ .platform_data = &c6x_plat_data,
+ },
+ .num_resources = 1,
+ .resource = &c6x_platram_resource,
+};
+#endif
+
+#ifdef CONFIG_TMS320C64X_GEMAC
+#if defined(CONFIG_TMS320C64X_GEMAC_0) || !defined(CONFIG_SOC_TMS320C6472)
+static struct resource emac_resources0[] = {
+ {
+ .name = "EMAC_REG_BASE",
+ .start = EMAC0_REG_BASE,
+ .end = EMAC0_REG_BASE + 0xFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ECTL_REG_BASE",
+ .start = ECTL0_REG_BASE,
+ .end = ECTL0_REG_BASE + 0x7FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "EMAC_DSC_BASE",
+ .start = EMAC0_DSC_BASE,
+ .end = EMAC0_DSC_BASE + 0x17FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "IRQ_SRC",
+ .start = IRQ_EMACRXINT,
+ .end = IRQ_EMACTXINT,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device emac_dev0 = {
+ .name = "EMAC",
+ .id = 0,
+ .resource = emac_resources0,
+ .num_resources = ARRAY_SIZE(emac_resources0),
+};
+#endif
+
+#ifdef CONFIG_TMS320C64X_GEMAC_1
+static struct resource emac_resources1[] = {
+ {
+ .name = "EMAC_REG_BASE",
+ .start = EMAC1_REG_BASE,
+ .end = EMAC1_REG_BASE + 0xFFF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "ECTL_REG_BASE",
+ .start = ECTL1_REG_BASE,
+ .end = ECTL1_REG_BASE + 0x7FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "EMAC_DSC_BASE",
+ .start = EMAC1_DSC_BASE,
+ .end = EMAC1_DSC_BASE + 0x17FF,
+ .flags = IORESOURCE_MEM,
+ },
+ {
+ .name = "IRQ_SRC",
+ .start = IRQ_EMACRXINT1,
+ .end = IRQ_EMACTXINT1,
+ .flags = IORESOURCE_IRQ,
+ },
+};
+
+static struct platform_device emac_dev1 = {
+ .name = "EMAC",
+ .id = 1,
+ .resource = emac_resources1,
+ .num_resources = ARRAY_SIZE(emac_resources1),
+};
+#endif
+
+static void setup_emac(void)
+{
+ int status;
+
+#if defined(CONFIG_TMS320C64X_GEMAC_0) || !defined(CONFIG_SOC_TMS320C6472)
+ status = platform_device_register(&emac_dev0);
+ if (status != 0)
+ pr_debug("setup_emac0 --> %d\n", status);
+#ifdef CONFIG_SOC_TMS320C6455
+ else {
+ unsigned long val;
+
+ /* Enable EMAC device (in regs PERLOCK & PERCFG0) */
+ val = DSCR_PERCFG0 | DSCR_B_PERCFG0_EMAC;
+ while (DSCR_PERCFG0 != val) {
+ DSCR_PERLOCK = DSCR_LOCKVAL;
+ DSCR_PERCFG0 = val;
+ }
+
+ /* Wait for enabling (reg PERSTAT0) */
+ while (((DSCR_PERSTAT0 & 0x1C0) >> 6) != 0x1)
+ ;
+ }
+#endif /* CONFIG_SOC_TMS320C6455 */
+#endif /* defined(CONFIG_TMS320C64X_GEMAC_0) || !defined(CONFIG_SOC_TMS320C6472) */
+
+#ifdef CONFIG_TMS320C64X_GEMAC_1
+ status = platform_device_register(&emac_dev1);
+ if (status != 0)
+ pr_debug("setup_emac1 --> %d\n", status);
+#ifdef CONFIG_SOC_TMS320C6472
+ else {
+ unsigned long val;
+ val = DSCR_DEVCTL | DSCR_B_DEVCTL_EMAC1;
+ while (DSCR_DEVCTL != val) {
+ DSCR_PERLOCK = DSCR_LOCKVAL;
+ DSCR_DEVCTL = val;
+ }
+ }
+#endif /* CONFIG_SOC_TMS320C6472 */
+#endif /* CONFIG_TMS320C64X_GEMAC_1 */
+}
+#else /* CONFIG_TMS320C64X_GEMAC */
+static void setup_emac(void) {}
+#endif /* CONFIG_TMS320C64X_GEMAC */
+
+#if defined(CONFIG_SOC_TMS320C6474)
+unsigned int arch_get_silicon_rev(void)
+{
+ u32 jtagid_val = *(u32 *) DSCR_JTAGID;
+ u32 silicon_rev = (jtagid_val >> 28) & 0xf;
+
+ return silicon_rev;
+}
+
+char *arch_compute_silicon_rev(u32 silicon_rev)
+{
+ char *str;
+ switch (silicon_rev) {
+ case 0x1:
+ str = "1.2";
+ break;
+ case 0x2:
+ str = "1.3";
+ break;
+ case 0x3:
+ str = "2.0";
+ break;
+ case 0x4:
+ str = "2.1";
+ break;
+ default:
+ str = "unknown";
+ break;
+ }
+ return str;
+}
+#endif
+
+static void init_pll(void)
+{
+#if defined(CONFIG_SOC_TMS320C6474) /* should be done elsewhere */
+ pll1_clearbit_reg(PLLCTL, PLLCTL_PLLENSRC);
+ pll1_clearbit_reg(PLLCTL, PLLCTL_PLLEN);
+
+ /* Wait 4 cycles of the slowest of PLLOUT or reference clock source (CLKIN).*/
+ __delay(100);
+
+ pll1_setbit_reg(PLLCTL, PLLCTL_PLLRST);
+ pll1_set_reg(PLLM, PLLM_VAL(20));
+
+ /*
+ * This can't be right. There is no previder here...
+ pll1_set_reg(PLLPREDIV, PLLPREDIV_VAL(10) | PLLPREDIV_EN);
+ */
+
+ pll1_wait_gostat();
+
+ /* Wait until GOSTAT bit is cleared*/
+ /* while(pll1_get_reg(PLL_PLLSTAT) & PLLSTAT_GOSTAT); */
+
+ pll1_set_reg(PLLDIV11, PLLDIV_RATIO(10) | PLLDIV_EN);
+ pll1_set_reg(PLLDIV13, PLLDIV_RATIO(6) | PLLDIV_EN);
+
+ pll1_setbit_reg(PLLCMD, PLLCMD_GOSTAT);
+
+ pll1_wait_gostat();
+
+ /* Wait until GOSTAT bit is cleared*/
+ /* while(pll1_get_reg(PLLSTAT) & PLLSTAT_GOSTAT); */
+
+ __delay(1000);
+
+ pll1_clearbit_reg(PLLCTL, PLLCTL_PLLRST);
+
+ __delay(4000);
+
+ pll1_setbit_reg(PLLCTL, PLLCTL_PLLEN);
+#endif
+
+#if defined(CONFIG_SOC_TMS320C6472) && defined(CONFIG_TMS320C64X_GEMAC)
+ /* PLL2 configuration (EMAC) */
+ pll2_clearbit_reg(PLLCTL, PLLCTL_PLLENSRC);
+ pll2_clearbit_reg(PLLCTL, PLLCTL_PLLEN);
+
+ /* Wait 4 cycles of the slowest of PLLOUT or reference clock source (CLKIN).*/
+ __delay(100);
+
+ pll2_setbit_reg(PLLCTL, PLLCTL_PLLRST);
+
+ /* Wait for PLL to properly reset.*/
+ __delay(4000);
+
+ pll2_clearbit_reg(PLLCTL, PLLCTL_PLLRST);
+
+ /* Wait for PLL to lock */
+ __delay(4000);
+
+ pll2_setbit_reg(PLLCTL, PLLCTL_PLLEN);
+#endif
+}
+
+static void init_power(void)
+{
+#if defined(CONFIG_SOC_TMS320C6474)
+
+ PSC_PDCTL0 |= 0x00000001;
+ PSC_MDCTL0 |= 0x00000003;
+ PSC_MDCTL1 |= 0x00000003;
+ PSC_MDCTL2 |= 0x00000003;
+
+ PSC_PDCTL1 |= 0x00000001;
+ PSC_MDCTL6 |= 0x00000003;
+
+ PSC_PDCTL2 |= 0x00000001;
+ PSC_MDCTL7 |= 0x00000003;
+
+ PSC_PDCTL3 |= 0x00000001;
+ PSC_MDCTL8 |= 0x00000003;
+
+ PSC_PDCTL4 |= 0x00000001;
+ PSC_MDCTL9 |= 0x00000003;
+
+ PSC_PDCTL5 |= 0x00000001;
+ PSC_MDCTL10 |= 0x00000003;
+
+ PSC_PTCMD |= 0x0000003f;
+
+#ifdef CONFIG_RAPIDIO_TCI648X
+ PSC_PDCTL2 |= 1;
+ PSC_MDCTL7 |= 3; /* sRIO */
+ PSC_PTCMD |= 4;
+
+#endif /* CONFIG_RAPIDIO_TCI648X */
+#endif /* CONFIG_SOC_TMS320C6474 */
+
+#ifdef CONFIG_SOC_TMS320C6472
+
+#ifdef CONFIG_TMS320C64X_GEMAC_0
+ PSC_MDCTL7 |= 0x00000103; /* GEMAC0 */
+#endif /* CONFIG_TMS320C64X_GEMAC_0 */
+
+#ifdef CONFIG_TMS320C64X_GEMAC_1
+ PSC_MDCTL8 |= 0x00000103; /* GEMAC1 */
+#endif /* CONFIG_TMS320C64X_GEMAC_1 */
+
+#ifdef CONFIG_RAPIDIO_TCI648X
+ PSC_MDCTL6 |= 0x00000103; /* SRIO */
+#endif /* CONFIG_RAPIDIO_TCI648X */
+
+ PSC_PTCMD |= 0x00000001;
+
+#endif/* CONFIG_SOC_TMS320C6472 */
+}
+
+void c6x_soc_setup_arch(void)
+{
+#if defined(CONFIG_SOC_TMS320C6474)
+ unsigned long val;
+#endif
+
+ /* Initialize C64x+ IRQs */
+ set_creg(ICR, -1);
+
+ init_pll();
+
+ init_power();
+
+#if defined(CONFIG_SOC_TMS320C6474)
+ /* Enable timers and devices (in regs PERLOCK & PERCFG0) */
+ DSCR_PERLOCK = DSCR_LOCKVAL;
+
+ DSCR_PERCFG0 = DSCR_B_PERCFG0_TIMER0
+ | DSCR_B_PERCFG0_TIMER1
+ | DSCR_B_PERCFG0_I2C
+ | DSCR_B_PERCFG0_GPIO
+ | DSCR_B_PERCFG0_EMAC; /* 0xc0015555 */
+
+ /* read for enabling (reg PERSTAT0) */
+ val = DSCR_PERSTAT0;
+
+ /* Wait 128 cycles */
+ __delay(22);
+#endif /* defined(CONFIG_SOC_TMS320C6474) */
+
+#if defined(CONFIG_SOC_TMS320C6472)
+
+ /* Do not allow user mode to access SoC device I/O */
+ DSCR_PRIVKEY = 0xbea7;
+ DSCR_PRIVPERM = 0xaaaaaaaa;
+ DSCR_PRIVKEY = 0;
+
+#endif /*defined(CONFIG_SOC_TMS320C6472) */
+
+#if defined(CONFIG_SOC_TMS320C6455)
+ /* Enable timers (in regs PERLOCK & PERCFG0) */
+ {
+ unsigned int mask = DSCR_B_PERCFG0_TIMER0 |
+ DSCR_B_PERCFG0_TIMER1;
+
+ while ((DSCR_PERCFG0 & mask) != mask) {
+ DSCR_PERLOCK = DSCR_LOCKVAL;
+ DSCR_PERCFG0 |= mask;
+ }
+ }
+
+ /* Wait for enabling (reg PERSTAT0) */
+ while (((DSCR_PERSTAT0 & 0x3E00) >> 9) != 0x9)
+ ;
+#endif /* defined(CONFIG_SOC_TMS320C6455) */
+
+ /* Initialize SoC resources */
+ iomem_resource.name = "Memory";
+ request_resource(&iomem_resource, &c6x_soc_res);
+}
+
+static int __init platform_arch_init(void)
+{
+ int status = 0;
+
+ /* Intialize EMAC SoC resources */
+ setup_emac();
+
+#if defined(CONFIG_MTD_PLATRAM) || defined(CONFIG_MTD_PLATRAM_MODULE)
+ if (c6x_platram_size) {
+
+ c6x_platram_resource.start = c6x_platram_start;
+ c6x_platram_resource.end = c6x_platram_start + c6x_platram_size - 1;
+
+ status = platform_device_register(&c6x_platram_device);
+ printk(KERN_ERR "Could not register platram device: %d\n", status);
+ }
+#endif
+ return status;
+}
+
+arch_initcall(platform_arch_init);
+
diff --git a/arch/c6x/platforms/sgmii.c b/arch/c6x/platforms/sgmii.c
new file mode 100644
index 0000000..90f62d0
--- /dev/null
+++ b/arch/c6x/platforms/sgmii.c
@@ -0,0 +1,83 @@
+/*
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2007, 2009 Texas Instruments Incorporated
+ * Author: Aurelien Jacquiot ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/netdevice.h>
+
+#include <asm/setup.h>
+#include <asm/sgmii.h>
+#include <asm/gemac.h>
+
+int sgmii_reset(void)
+{
+ sgmii_setbit_reg(SGMII_SRESET_REG, SGMII_SRESET_RESET); /* soft reset */
+ while (sgmii_get_reg(SGMII_SRESET_REG) != 0x0)
+ ;
+ sgmii_setbit_reg(SGMII_CTL_REG, SGMII_CTL_MASTER);
+
+ return 0;
+}
+
+int sgmii_config(struct sgmii_config_s *config)
+{
+ unsigned int val1 = 0, val2 = 0;
+
+ if (!config)
+ return -1;
+
+ if (config->loopback) {
+ val1 = SGMII_CTL_MASTER | SGMII_CTL_LOOPBACK | SGMII_CTL_AUTONEG; /* 0x35 */
+ val2 = 0x9801;
+ }
+
+ if (config->master) {
+ val1 = SGMII_CTL_MASTER;
+ val2 = 0x9801; /* advertise fullduplex gigabit */
+ } else {
+ val1 = 0;
+ val2 = 0x01; /* advertise fullduplex gigabit */
+ }
+
+ if (config->autoneg)
+ val1 |= SGMII_CTL_AUTONEG;
+
+ sgmii_set_reg(SGMII_SRESET_REG, SGMII_SRESET_RTRESET); /* RT soft reset */
+ sgmii_set_reg(SGMII_CTL_REG, val1);
+ sgmii_clearbit_reg(SGMII_SRESET_REG, SGMII_SRESET_RTRESET);
+
+ sgmii_set_reg(SGMII_MRADV_REG, val2);
+#ifndef CONFIG_TMS320DM648
+ sgmii_set_reg(SGMII_TXCFG_REG, config->txconfig);
+ sgmii_set_reg(SGMII_RXCFG_REG, config->rxconfig);
+ sgmii_set_reg(SGMII_AUXCFG_REG, config->auxconfig);
+#else
+ sgmii_set_reg(SERDES_KEY_REG, SERDES_KEY_VAL);
+ sgmii_set_reg(SERDES_PLL_REG, config->auxconfig);
+ for (i = 0; i < 2500; i++)
+ asm(" nop");
+ sgmii_set_reg(SERDES_RX0_REG, config->rxconfig);
+ sgmii_set_reg(SERDES_TX0_REG, config->txconfig);
+#endif
+ if (config->autoneg) {
+ unsigned int done = 0x5;
+ unsigned int stat;
+
+ /* Wait for auto-negotiation*/
+ do {
+ stat = sgmii_get_reg(SGMII_STATUS_REG);
+ stat &= done;
+ } while (stat != done);
+ }
+
+ return 0;
+}
+
+
--
1.6.2.5

2011-05-11 21:06:50

by Mark Salter

[permalink] [raw]
Subject: [PATCH 13/16] C6X: add drivers/platform/c6x files

This patch adds driver support for miscellaneous drivers for hardware found
on C64x DSP chips but not really part of the CPU core. These could have been
put under arch/c6x/kernel, but that would get cluttered pretty quickly as
new SoC parts are supported.

Signed-off-by: Mark Salter <[email protected]>
---
drivers/platform/Kconfig | 4 +
drivers/platform/Makefile | 1 +
drivers/platform/c6x/Kconfig | 27 ++
drivers/platform/c6x/Makefile | 8 +
drivers/platform/c6x/irq-c64xplus.c | 583 ++++++++++++++++++++++++++++++++++
drivers/platform/c6x/pll-tci648x.c | 433 +++++++++++++++++++++++++
drivers/platform/c6x/timer-tci648x.c | 121 +++++++
drivers/platform/c6x/tsc-c64xplus.c | 53 +++
8 files changed, 1230 insertions(+), 0 deletions(-)
create mode 100644 drivers/platform/c6x/Kconfig
create mode 100644 drivers/platform/c6x/Makefile
create mode 100644 drivers/platform/c6x/irq-c64xplus.c
create mode 100644 drivers/platform/c6x/pll-tci648x.c
create mode 100644 drivers/platform/c6x/timer-tci648x.c
create mode 100644 drivers/platform/c6x/tsc-c64xplus.c

diff --git a/drivers/platform/Kconfig b/drivers/platform/Kconfig
index 8390dca..df334ed 100644
--- a/drivers/platform/Kconfig
+++ b/drivers/platform/Kconfig
@@ -1,3 +1,7 @@
if X86
source "drivers/platform/x86/Kconfig"
endif
+
+if TMS320C6X
+source "drivers/platform/c6x/Kconfig"
+endif
diff --git a/drivers/platform/Makefile b/drivers/platform/Makefile
index 782953a..bd9e0e3 100644
--- a/drivers/platform/Makefile
+++ b/drivers/platform/Makefile
@@ -3,3 +3,4 @@
#

obj-$(CONFIG_X86) += x86/
+obj-$(CONFIG_TMS320C6X) += c6x/
diff --git a/drivers/platform/c6x/Kconfig b/drivers/platform/c6x/Kconfig
new file mode 100644
index 0000000..a950fb8
--- /dev/null
+++ b/drivers/platform/c6x/Kconfig
@@ -0,0 +1,27 @@
+#
+# C6X Platform Specific Drivers
+#
+
+menuconfig C6X_PLATFORM_DEVICES
+ bool "C6X Platform Specific Device Drivers"
+ default y
+ depends on TMS320C6X
+ ---help---
+ Say Y here to get to see options for device drivers for various
+ c64x platforms. This option alone does not add any kernel code.
+
+ If you say N, all options in this submenu will be skipped and disabled.
+
+if C6X_PLATFORM_DEVICES
+
+config PLL_TCI648X
+ bool "PLL_TCI648X"
+ depends on COMMON_CLKDEV
+
+config TIMER_TCI648X
+ bool "TIMER_TCI648X"
+
+config PIC_C64XPLUS
+ bool "C64X+ Megamodule Interrupt Controller"
+
+endif # C6X_PLATFORM_DEVICES
diff --git a/drivers/platform/c6x/Makefile b/drivers/platform/c6x/Makefile
new file mode 100644
index 0000000..2f9be75
--- /dev/null
+++ b/drivers/platform/c6x/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for drivers/platform/c6x
+#
+
+obj-$(CONFIG_PLL_TCI648X) += pll-tci648x.o
+obj-$(CONFIG_TMS320C64XPLUS) += tsc-c64xplus.o
+obj-$(CONFIG_TIMER_TCI648X) += timer-tci648x.o
+obj-$(CONFIG_PIC_C64XPLUS) += irq-c64xplus.o
diff --git a/drivers/platform/c6x/irq-c64xplus.c b/drivers/platform/c6x/irq-c64xplus.c
new file mode 100644
index 0000000..4eff863
--- /dev/null
+++ b/drivers/platform/c6x/irq-c64xplus.c
@@ -0,0 +1,583 @@
+/*
+ * Support for C64x+ Megamodule Interrupt Controller
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Contributed by: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/types.h>
+#include <linux/sched.h>
+#include <linux/kernel_stat.h>
+#include <linux/errno.h>
+#include <linux/init.h>
+#include <linux/hardirq.h>
+#include <linux/seq_file.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/io.h>
+#include <linux/hardirq.h>
+
+#include <asm/system.h>
+#include <asm/irq.h>
+#include <asm/traps.h>
+#include <asm/page.h>
+#include <asm/hardware.h>
+
+#define IRQ_UNMAPPED 0xffff
+
+#define NR_MEGAMOD_COMBINERS 4
+
+#ifdef CONFIG_SOC_TMS320C6474
+#define NR_CIC_COMBINERS 2
+#define NR_CIC_OUTPUTS 16
+#else
+#define NR_CIC_COMBINERS 0
+#endif
+
+#define NR_COMBINERS (NR_MEGAMOD_COMBINERS + NR_CIC_COMBINERS)
+
+struct combiner_handler_info {
+ volatile uint32_t *mevtflag;
+ volatile uint32_t *evtclr;
+ uint16_t irqmap[32];
+};
+
+struct combiner_mask_info {
+ int irq_base;
+ volatile uint32_t *evtmask;
+};
+
+struct c6x_irq_chip {
+ struct irq_chip chip;
+ struct combiner_mask_info *minfo;
+};
+
+static struct combiner_mask_info megamod_mask_info[NR_MEGAMOD_COMBINERS];
+static struct combiner_handler_info megamod_handler_info[NR_MEGAMOD_COMBINERS];
+
+uint16_t prio_to_irq[NR_SYS_IRQS];
+
+static uint8_t irq_to_prio[NR_IRQS];
+
+/* The 16 SoC GPIOs can span more than one megamodule */
+#define NR_GPIO_CHIPS 2
+
+static struct c6x_irq_chip direct_chips[(INT15 - INT4) + 1];
+static struct c6x_irq_chip gpio_chips[NR_GPIO_CHIPS];
+static struct c6x_irq_chip *prio_saved_chips[NR_SYS_IRQS];
+
+#if NR_CIC_COMBINERS > 0
+static struct combiner_mask_info cic_mask_info[NR_CIC_COMBINERS];
+static struct combiner_handler_info cic_handler_info[NR_CIC_COMBINERS];
+
+static uint8_t cic_output_to_evt[NR_CIC_OUTPUTS];
+static uint8_t cic_evt_to_output[NR_CIC_IRQS];
+static struct c6x_irq_chip cic_mapped_chips[CIC_MAPLEN - NR_CIC_COMBINERS];
+static struct c6x_irq_chip *cic_saved_chips[CIC_MAPLEN - NR_CIC_COMBINERS];
+#endif
+
+/* lock protecting irq mappings */
+static spinlock_t map_lock;
+
+static void mask_direct(struct irq_data *data)
+{
+ uint16_t prio;
+
+ BUG_ON(data->irq >= NR_IRQS);
+ prio = irq_to_prio[data->irq];
+ BUG_ON(prio >= NR_SYS_IRQS);
+ and_creg(IER, ~(1 << prio));
+}
+
+static void unmask_direct(struct irq_data *data)
+{
+ uint16_t prio;
+
+ BUG_ON(data->irq >= NR_IRQS);
+ prio = irq_to_prio[data->irq];
+ BUG_ON(prio >= NR_SYS_IRQS);
+ or_creg(IER, 1 << prio);
+}
+
+static const char * const direct_chip_names[] = {
+ "direct-4",
+ "direct-5",
+ "direct-6",
+ "direct-7",
+ "direct-8",
+ "direct-9",
+ "direct-10",
+ "direct-11",
+ "direct-12",
+ "direct-13",
+ "direct-14",
+ "direct-15",
+};
+
+#if NR_CIC_COMBINERS > 0
+/*
+ * CIC IRQs mapped directly to megamodule use chip data from the megamodule
+ * combiner since the megamodule combiner will controlling masking. All other
+ * CIC IRQs use CIC combiner chip data.
+ */
+static inline int cic_mapped_irq(uint16_t irq)
+{
+ uint8_t output;
+
+ if (irq < IRQ_CIC_START || irq >= (IRQ_CIC_START + NR_CIC_IRQS))
+ return irq;
+
+ /* the CIC combined IRQs are hardwired */
+ if (irq < (IRQ_CIC_START + NR_CIC_COMBINERS))
+ return CIC_MAPBASE + (irq - IRQ_CIC_START);
+
+ /* the other CIC events may or may not be mapped to megamodule */
+ output = cic_evt_to_output[irq - IRQ_CIC_START];
+ if (output)
+ return CIC_MAPBASE + output;
+
+ return irq;
+}
+#else
+#define cic_mapped_irq(i) (i)
+#endif
+
+#define c6x_irq_to_chip(i) ((struct c6x_irq_chip *)irq_to_desc((i))->chip)
+
+static void mask_combined(struct irq_data *data)
+{
+ struct c6x_irq_chip *chip = (struct c6x_irq_chip *)data->chip;
+ int irq = data->irq;
+
+ irq = cic_mapped_irq(irq);
+ *chip->minfo->evtmask |= (1 << (irq - chip->minfo->irq_base));
+}
+
+static void unmask_combined(struct irq_data *data)
+{
+ struct c6x_irq_chip *chip = (struct c6x_irq_chip *)data->chip;
+ int irq = data->irq;
+
+ irq = cic_mapped_irq(irq);
+ *chip->minfo->evtmask &= ~(1 << (irq - chip->minfo->irq_base));
+}
+
+#define __CHIP(namestr, i, m, u) \
+ { \
+ .chip = { .name = namestr #i, \
+ .irq_mask = m, \
+ .irq_unmask = u, \
+ }, \
+ }
+
+/* Combiner chips */
+#define MEGAMOD_CHIP(i) \
+ __CHIP("combiner-", i, mask_combined, unmask_combined)
+
+static struct c6x_irq_chip megamod_chips[] = {
+ MEGAMOD_CHIP(0),
+ MEGAMOD_CHIP(1),
+ MEGAMOD_CHIP(2),
+ MEGAMOD_CHIP(3),
+};
+
+#if NR_CIC_COMBINERS > 0
+
+#define CIC_CHIP(i) \
+ __CHIP("cicombiner-", i, mask_combined, unmask_combined)
+
+static struct c6x_irq_chip cic_chips[] = {
+ CIC_CHIP(0),
+#if NR_CIC_COMBINERS > 1
+ CIC_CHIP(1),
+#endif
+#if NR_CIC_COMBINERS > 2
+ CIC_CHIP(2),
+#endif
+#if NR_CIC_COMBINERS > 3
+ CIC_CHIP(3),
+#endif
+};
+#endif /* NR_CIC_COMBINERS > 0 */
+
+/*
+ * When handling IRQs through the CIC, ack after the handler runs.
+ * For IRQs through the megamodule, ack before handler runs.
+ */
+#if NR_CIC_COMBINERS
+#define PRE_ACK (irq < IRQ_CIC_START || \
+ irq >= (IRQ_CIC_START + NR_CIC_COMBINERS))
+#else
+#define PRE_ACK 1
+#endif
+
+static void handle_combined_irq(unsigned int irq, struct irq_desc *desc)
+{
+ struct combiner_handler_info *info = irq_desc_get_handler_data(desc);
+ unsigned long events;
+ int n;
+
+ while ((events = *info->mevtflag) != 0) {
+ n = __ffs(events);
+ irq = info->irqmap[n]; /* irq to handle */
+
+ if (PRE_ACK)
+ *info->evtclr = (1 << n);
+
+ generic_handle_irq(irq);
+
+ if (!PRE_ACK)
+ *info->evtclr = (1 << n);
+ }
+}
+
+/*
+ * Setup megamodule event mappings.
+ */
+static inline void __irq_megamod_map(unsigned int src, unsigned int dst)
+{
+ uint32_t val;
+ int offset, nr_srcs;
+
+ nr_srcs = (NR_MEGAMOD_COMBINERS * 32);
+
+ BUG_ON(dst < INT4 || dst > INT15);
+ BUG_ON(src >= nr_srcs);
+
+ /* each mux register controls four outputs */
+ offset = (dst & 3) << 3;
+ val = IC_INTMUX[dst >> 2];
+ val &= ~((nr_srcs - 1) << offset);
+ val |= ((src & (nr_srcs - 1)) << offset);
+ IC_INTMUX[dst >> 2] = val;
+}
+
+/*
+ * Map a C64x+ megamodule event to a CPU core priority interrupt.
+ */
+void irq_map(unsigned int irq_src, unsigned int prio)
+{
+ struct irq_desc *desc;
+ struct c6x_irq_chip *chip, *direct;
+ unsigned long flags;
+ unsigned int prio_idx = prio - INT4;
+
+ if (prio < INT4 || prio > INT15)
+ return;
+
+ /* only map megamodule event sources here */
+ if (irq_src >= (NR_MEGAMOD_COMBINERS * 32))
+ return;
+
+ spin_lock_irqsave(&map_lock, flags);
+
+ /* make sure this IRQ is not mapped to another core IRQ */
+ if (irq_to_prio[irq_src])
+ goto out_unlock;
+
+ /* make sure no other IRQ is mapped to the requested priority */
+ if (prio_to_irq[prio] != IRQ_UNMAPPED)
+ goto out_unlock;
+
+#if NR_CIC_COMBINERS > 0
+ /* handle mapping for IRQs coming from CIC */
+ if (irq_src >= CIC_MAPBASE &&
+ irq_src < (CIC_MAPBASE + CIC_MAPLEN)) {
+ uint8_t cic_src, output = (irq_src - CIC_MAPBASE);
+ uint16_t cic_irq;
+ struct irq_data *data;
+
+ if (output >= NR_CIC_COMBINERS) {
+ cic_src = cic_output_to_evt[output];
+ if (cic_src < NR_CIC_COMBINERS)
+ goto out_unlock;
+ cic_irq = IRQ_CIC_START + cic_src;
+ } else
+ cic_irq = IRQ_CIC_START + output;
+
+ desc = irq_to_desc(cic_irq);
+ data = &desc->irq_data;
+ chip = (struct c6x_irq_chip *)data->chip;
+
+ /* mask combined CIC irq in megamodule combiner */
+ if (output < NR_CIC_COMBINERS)
+ mask_combined(data);
+
+ direct = &direct_chips[prio_idx];
+ *direct = *chip;
+ direct->chip.name = direct_chip_names[prio_idx];
+ direct->chip.irq_mask = mask_direct;
+ direct->chip.irq_unmask = unmask_direct;
+
+ prio_saved_chips[prio] = chip;
+ data->chip = (struct irq_chip *)direct;
+ irq_to_prio[cic_irq] = prio;
+ prio_to_irq[prio] = cic_irq;
+
+ __irq_megamod_map(irq_src, prio);
+
+ if (output < NR_CIC_COMBINERS)
+ irq_set_chained_handler(irq_src, handle_combined_irq);
+
+ goto out_unlock;
+ }
+#endif
+ desc = irq_to_desc(irq_src);
+ chip = (struct c6x_irq_chip *)desc->irq_data.chip;
+
+ direct = &direct_chips[prio_idx];
+ if (irq_src < NR_MEGAMOD_COMBINERS)
+ memset(&direct->chip, 0, sizeof(direct->chip));
+ else
+ *direct = *(struct c6x_irq_chip *)chip;
+ direct->chip.name = direct_chip_names[prio_idx];
+ direct->chip.irq_mask = mask_direct;
+ direct->chip.irq_unmask = unmask_direct;
+
+ prio_saved_chips[prio] = chip;
+ irq_set_chip(irq_src, (struct irq_chip *)direct);
+ irq_to_prio[irq_src] = prio;
+ prio_to_irq[prio] = irq_src;
+
+ __irq_megamod_map(irq_src, prio);
+
+ if (irq_src < NR_MEGAMOD_COMBINERS) {
+ irq_set_handler_data(irq_src, &megamod_handler_info[irq_src]);
+ irq_set_chained_handler(irq_src, handle_combined_irq);
+ }
+
+out_unlock:
+ spin_unlock_irqrestore(&map_lock, flags);
+}
+EXPORT_SYMBOL(irq_map);
+
+
+#if NR_CIC_COMBINERS > 0
+/*
+ * Setup CIC event mappings on given core.
+ */
+static inline void __irq_cic_map(int core, unsigned int src, unsigned int dst)
+{
+ uint32_t val;
+ int offset, nr_srcs;
+
+ nr_srcs = (NR_CIC_COMBINERS * 32);
+
+ /* output0 and output1 are hardwired */
+ BUG_ON(dst < 2 || dst > 15);
+ BUG_ON(src >= nr_srcs);
+
+ offset = (dst & 3) << 3;
+ val = CIC_MUX(core)[dst >> 2];
+ val &= ~(0x7f << offset);
+ val |= ((src & 0x7f) << offset);
+ CIC_MUX(core)[dst >> 2] = val;
+}
+
+/*
+ * Map a C64x+ CIC IRQ to a megamodule event
+ *
+ * Do nothing for CIC combined IRQs. They are always mapped.
+ */
+void irq_cic_map(unsigned int irq_src, unsigned int irq_dst)
+{
+ struct irq_desc *desc;
+ struct c6x_irq_chip *chip, *mmchip;
+ unsigned long flags;
+ int src, output;
+ struct combiner_handler_info *info;
+ unsigned int idx = irq_dst - (CIC_MAPBASE + NR_CIC_COMBINERS);
+
+ if (irq_dst < (CIC_MAPBASE + NR_CIC_COMBINERS) ||
+ irq_dst >= (CIC_MAPBASE + CIC_MAPLEN))
+ return;
+
+ /* only map CIC event sources */
+ if (irq_src < (IRQ_CIC_START + NR_CIC_COMBINERS) ||
+ irq_src >= (IRQ_CIC_START + NR_CIC_IRQS))
+ return;
+
+ src = irq_src - IRQ_CIC_START;
+ output = irq_dst - CIC_MAPBASE;
+
+ spin_lock_irqsave(&map_lock, flags);
+
+ /* make sure this IRQ is not already mapped */
+ if (cic_evt_to_output[src])
+ goto out_unlock;
+
+ /* make sure the requested output is not in use */
+ if (cic_output_to_evt[output])
+ goto out_unlock;
+
+ /* record the mapping */
+ cic_evt_to_output[src] = output;
+ cic_output_to_evt[output] = src;
+
+ mmchip = &megamod_chips[(CIC_MAPBASE + output) / 32];
+ info = &megamod_handler_info[(CIC_MAPBASE + output) / 32];
+ info->irqmap[(CIC_MAPBASE + output) & 31] = irq_src;
+
+ desc = irq_to_desc(irq_src);
+ cic_saved_chips[idx] = (struct c6x_irq_chip *)desc->irq_data.chip;
+
+ chip = &cic_mapped_chips[idx];
+ *chip = *(struct c6x_irq_chip *)desc->irq_data.chip;
+ chip->chip.name = mmchip->chip.name;
+ chip->minfo = mmchip->minfo;
+
+ desc->irq_data.chip = (struct irq_chip *)chip;
+
+ __irq_cic_map(get_coreid(), src, output);
+out_unlock:
+ spin_unlock_irqrestore(&map_lock, flags);
+}
+EXPORT_SYMBOL(irq_cic_map);
+
+/*
+ * Map a CIC source to a give CIC output event for a given core or TPCC
+ */
+void cic_raw_map(unsigned int src, unsigned int dst, int core)
+{
+ __irq_cic_map(core, src, dst);
+}
+EXPORT_SYMBOL(cic_raw_map);
+
+#endif /* NR_CIC_COMBINERS > 0 */
+
+void __init init_pic_c64xplus(void)
+{
+ int i, j, idx;
+ struct irq_desc *desc;
+ struct c6x_irq_chip *c6x_chip, *last_chip;
+ struct irq_chip *chip;
+ struct combiner_mask_info *minfo;
+ struct combiner_handler_info *hinfo;
+#if NR_CIC_COMBINERS > 0
+ unsigned core = get_coreid();
+#endif
+
+ spin_lock_init(&map_lock);
+
+ /* initialize chip info */
+ minfo = &megamod_mask_info[0];
+ hinfo = &megamod_handler_info[0];
+ for (i = 0; i < NR_MEGAMOD_COMBINERS; i++) {
+ minfo->irq_base = IRQ_EVT0 + (i * 32);
+ minfo->evtmask = &IC_EVTMASK[i];
+ hinfo->mevtflag = &IC_MEVTFLAG[i];
+ hinfo->evtclr = &IC_EVTCLR[i];
+ for (j = 0; j < 32; j++)
+ hinfo->irqmap[j] = minfo->irq_base + j;
+ minfo++;
+ hinfo++;
+ }
+#if NR_CIC_COMBINERS > 0
+ minfo = &cic_mask_info[0];
+ hinfo = &cic_handler_info[0];
+ for (i = 0; i < NR_CIC_COMBINERS; i++) {
+ minfo->irq_base = IRQ_CIC_START + (i * 32);
+ minfo->evtmask = &CIC_EVTMASK(core)[i];
+ hinfo->mevtflag = &CIC_MEVTFLAG(core)[i];
+ hinfo->evtclr = &CIC_EVTCLR(core)[i];
+ for (j = 0; j < 32; j++)
+ hinfo->irqmap[j] = minfo->irq_base + j;
+ minfo++;
+ hinfo++;
+ }
+#endif
+
+ /* initialize mapping arrays */
+ for (i = 0; i < NR_SYS_IRQS; i++)
+ prio_to_irq[i] = IRQ_UNMAPPED;
+ memset(&irq_to_prio[0], 0, sizeof(irq_to_prio));
+#if NR_CIC_COMBINERS > 0
+ memset(&cic_output_to_evt[0], 0, sizeof(cic_output_to_evt));
+ memset(&cic_evt_to_output[0], 0, sizeof(cic_evt_to_output));
+#endif
+
+ /* initialize megamodule combined IRQs */
+ for (i = 0; i < NR_MEGAMOD_COMBINERS; i++) {
+ desc = irq_to_desc(i);
+
+ IC_EVTMASK[i] = ~0; /* mask all events */
+ IC_EVTCLR[i] = ~0; /* clear all events */
+
+ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_bad_irq);
+
+ megamod_chips[i].minfo = &megamod_mask_info[i];
+ irq_set_handler_data(i, &megamod_handler_info[i]);
+ }
+
+ /* initialize individual megamodule IRQs */
+ for (i = NR_MEGAMOD_COMBINERS; i < (NR_MEGAMOD_COMBINERS * 32); i++) {
+ chip = (struct irq_chip *)&megamod_chips[i / 32];
+ irq_set_chip_and_handler(i, chip, handle_level_irq);
+ }
+
+#if NR_CIC_COMBINERS > 0
+ /* megamodule IRQs coming from CIC cannot be used directly */
+ for (i = CIC_MAPBASE; i < (CIC_MAPBASE + CIC_MAPLEN); i++)
+ irq_set_chip_and_handler(i, &dummy_irq_chip, handle_bad_irq);
+
+ /* CIC combined IRQs are hardwired to CIC_MAPBASE in megamodule */
+ for (i = 0; i < NR_CIC_COMBINERS; i++) {
+ int irq = IRQ_CIC_START + i;
+
+ CIC_EVTMASK(core)[i] = ~0; /* mask all events */
+ CIC_EVTCLR(core)[i] = ~0; /* clear all events */
+
+ cic_chips[i].minfo = &cic_mask_info[i];
+
+ /* chip info for megamodule combiner we are wired through */
+ chip = (struct irq_chip *)&megamod_chips[(CIC_MAPBASE + i)/32];
+ hinfo = &megamod_handler_info[(CIC_MAPBASE + i) / 32];
+
+ /* redirect megamodule irq to right place */
+ hinfo->irqmap[(CIC_MAPBASE + i) & 31] = irq;
+
+ irq_set_chip(irq, chip);
+ irq_set_handler_data(irq, &cic_handler_info[i]);
+ irq_set_chained_handler(irq, handle_combined_irq);
+ }
+
+ /* initialize individual CIC IRQs */
+ for (i = NR_CIC_COMBINERS; i < (NR_CIC_COMBINERS * 32); i++) {
+ int irq = IRQ_CIC_START + i;
+
+ irq_set_chip(irq, (struct irq_chip *)&cic_chips[i / 32]);
+ irq_set_handler(irq, handle_level_irq);
+ }
+
+ /*
+ * clear again megamodule combined IRQs because spurious CIC interrupts
+ * may have occur after the CIC initialization.
+ */
+ for (i = 0; i < NR_MEGAMOD_COMBINERS; i++)
+ IC_EVTCLR[i] = ~0; /* clear all events */
+#endif
+
+ /*
+ * GPIO interrupts need separate copies of megamodule chips
+ * so gpio code can add edge triggering support.
+ */
+ last_chip = NULL;
+ idx = 0;
+ for (i = IRQ_GPIO_START; i <= IRQ_GPIO15; i++) {
+ c6x_chip = (struct c6x_irq_chip *)irq_to_desc(i)->irq_data.chip;
+ if (c6x_chip != last_chip) {
+ last_chip = c6x_chip;
+ gpio_chips[idx++] = *c6x_chip;
+ }
+ irq_to_desc(i)->irq_data.chip = &gpio_chips[idx - 1].chip;
+ }
+
+ /* map megamodule combined IRQs to low-priority core IRQs */
+ irq_map(IRQ_EVT0, INT12);
+ irq_map(IRQ_EVT1, INT13);
+ irq_map(IRQ_EVT2, INT14);
+ irq_map(IRQ_EVT3, INT15);
+}
diff --git a/drivers/platform/c6x/pll-tci648x.c b/drivers/platform/c6x/pll-tci648x.c
new file mode 100644
index 0000000..ae15659
--- /dev/null
+++ b/drivers/platform/c6x/pll-tci648x.c
@@ -0,0 +1,433 @@
+/*
+ * Clock and PLL control for TCI648x devices
+ *
+ * Copyright (C) 2010 Texas Instruments.
+ * Contributed by: Mark Salter <[email protected]>
+ *
+ * Copied heavily from arm/mach-davinci/clock.c, so:
+ *
+ * Copyright (C) 2006-2007 Texas Instruments.
+ * Copyright (C) 2008-2009 Deep Root Systems, LLC
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/init.h>
+#include <linux/errno.h>
+#include <linux/clk.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/io.h>
+#include <linux/delay.h>
+
+#include <asm/clock.h>
+
+static LIST_HEAD(clocks);
+static DEFINE_MUTEX(clocks_mutex);
+static DEFINE_SPINLOCK(clockfw_lock);
+
+static void __clk_enable(struct clk *clk)
+{
+ if (clk->parent)
+ __clk_enable(clk->parent);
+ clk->usecount++;
+}
+
+static void __clk_disable(struct clk *clk)
+{
+ if (WARN_ON(clk->usecount == 0))
+ return;
+ --clk->usecount;
+
+ if (clk->parent)
+ __clk_disable(clk->parent);
+}
+
+int clk_enable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ __clk_enable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_enable);
+
+void clk_disable(struct clk *clk)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ __clk_disable(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+}
+EXPORT_SYMBOL(clk_disable);
+
+unsigned long clk_get_rate(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_get_rate);
+
+long clk_round_rate(struct clk *clk, unsigned long rate)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (clk->round_rate)
+ return clk->round_rate(clk, rate);
+
+ return clk->rate;
+}
+EXPORT_SYMBOL(clk_round_rate);
+
+/* Propagate rate to children */
+static void propagate_rate(struct clk *root)
+{
+ struct clk *clk;
+
+ list_for_each_entry(clk, &root->children, childnode) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+}
+
+int clk_set_rate(struct clk *clk, unsigned long rate)
+{
+ unsigned long flags;
+ int ret = -EINVAL;
+
+ if (clk == NULL || IS_ERR(clk))
+ return ret;
+
+ if (clk->set_rate)
+ ret = clk->set_rate(clk, rate);
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (ret == 0) {
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ }
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return ret;
+}
+EXPORT_SYMBOL(clk_set_rate);
+
+int clk_set_parent(struct clk *clk, struct clk *parent)
+{
+ unsigned long flags;
+
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ /* Cannot change parent on enabled clock */
+ if (WARN_ON(clk->usecount))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ clk->parent = parent;
+ list_del_init(&clk->childnode);
+ list_add(&clk->childnode, &clk->parent->children);
+ mutex_unlock(&clocks_mutex);
+
+ spin_lock_irqsave(&clockfw_lock, flags);
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+ propagate_rate(clk);
+ spin_unlock_irqrestore(&clockfw_lock, flags);
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_set_parent);
+
+int clk_register(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return -EINVAL;
+
+ if (WARN(clk->parent && !clk->parent->rate,
+ "CLK: %s parent %s has no rate!\n",
+ clk->name, clk->parent->name))
+ return -EINVAL;
+
+ mutex_lock(&clocks_mutex);
+ list_add_tail(&clk->node, &clocks);
+ if (clk->parent)
+ list_add_tail(&clk->childnode, &clk->parent->children);
+ mutex_unlock(&clocks_mutex);
+
+ /* If rate is already set, use it */
+ if (clk->rate)
+ return 0;
+
+ /* Else, see if there is a way to calculate it */
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+
+ /* Otherwise, default to parent rate */
+ else if (clk->parent)
+ clk->rate = clk->parent->rate;
+
+ return 0;
+}
+EXPORT_SYMBOL(clk_register);
+
+void clk_unregister(struct clk *clk)
+{
+ if (clk == NULL || IS_ERR(clk))
+ return;
+
+ mutex_lock(&clocks_mutex);
+ list_del(&clk->node);
+ list_del(&clk->childnode);
+ mutex_unlock(&clocks_mutex);
+}
+EXPORT_SYMBOL(clk_unregister);
+
+static unsigned long clk_sysclk_recalc(struct clk *clk)
+{
+ u32 v, plldiv = 0;
+ struct pll_data *pll;
+ unsigned long rate = clk->rate;
+
+ if (WARN_ON(!clk->parent))
+ return rate;
+
+ rate = clk->parent->rate;
+
+ /* the parent must be a PLL */
+ if (WARN_ON(!clk->parent->pll_data))
+ return rate;
+
+ pll = clk->parent->pll_data;
+
+ /* If pre-PLL, source clock is before the multiplier and divider(s) */
+ if (clk->flags & PRE_PLL)
+ rate = pll->input_rate;
+
+ if (!clk->div) {
+ pr_debug("%s: (no divider) rate = %lu KHz\n",
+ clk->name, rate / 1000);
+ return rate;
+ }
+
+ if (clk->flags & FIXED_DIV_PLL) {
+ rate /= clk->div;
+ pr_debug("%s: (fixed divide by %d) rate = %lu KHz\n",
+ clk->name, clk->div, rate / 1000);
+ return rate;
+ }
+
+ v = __raw_readl(pll->base + clk->div);
+ if (v & PLLDIV_EN)
+ plldiv = (v & PLLDIV_RATIO_MASK) + 1;
+
+ if (plldiv == 0)
+ plldiv = 1;
+
+ rate /= plldiv;
+
+ pr_debug("%s: (divide by %d) rate = %lu KHz\n",
+ clk->name, plldiv, rate / 1000);
+
+ return rate;
+}
+
+static unsigned long clk_leafclk_recalc(struct clk *clk)
+{
+ if (WARN_ON(!clk->parent))
+ return clk->rate;
+
+ pr_debug("%s: (parent %s) rate = %lu KHz\n",
+ clk->name, clk->parent->name, clk->parent->rate / 1000);
+
+ return clk->parent->rate;
+}
+
+static unsigned long clk_pllclk_recalc(struct clk *clk)
+{
+ u32 ctrl, mult = 1, prediv = 1;
+ u8 bypass;
+ struct pll_data *pll = clk->pll_data;
+ unsigned long rate = clk->rate;
+
+ if (clk->flags & FIXED_RATE_PLL)
+ return rate;
+
+ pll->base = ioremap(pll->phys_base, 1024);
+ ctrl = __raw_readl(pll->base + PLLCTL);
+ rate = pll->input_rate = clk->parent->rate;
+
+ if (ctrl & PLLCTL_PLLEN) {
+ bypass = 0;
+ mult = __raw_readl(pll->base + PLLM);
+ mult = (mult & PLLM_PLLM_MASK) + 1;
+ } else
+ bypass = 1;
+
+ if (pll->flags & PLL_HAS_PREDIV) {
+ prediv = __raw_readl(pll->base + PREDIV);
+ if (prediv & PLLDIV_EN)
+ prediv = (prediv & PLLDIV_RATIO_MASK) + 1;
+ else
+ prediv = 1;
+ }
+
+ if (!bypass) {
+ rate /= prediv;
+ rate *= mult;
+ }
+
+ pr_debug("PLL%d: input = %lu MHz [ ",
+ pll->num, clk->parent->rate / 1000000);
+ if (bypass)
+ pr_debug("bypass ");
+ if (prediv > 1)
+ pr_debug("/ %d ", prediv);
+ if (mult > 1)
+ pr_debug("* %d ", mult);
+ pr_debug("] --> %lu MHz output.\n", rate / 1000000);
+
+ return rate;
+}
+
+
+int __init c6x_clk_init(struct clk_lookup *clocks)
+{
+ struct clk_lookup *c;
+ struct clk *clk;
+ size_t num_clocks = 0;
+
+ for (c = clocks; c->clk; c++) {
+ clk = c->clk;
+
+ INIT_LIST_HEAD(&clk->node);
+ INIT_LIST_HEAD(&clk->children);
+ INIT_LIST_HEAD(&clk->childnode);
+
+ if (!clk->recalc) {
+
+ /* Check if clock is a PLL */
+ if (clk->pll_data)
+ clk->recalc = clk_pllclk_recalc;
+
+ /* Else, if it is a PLL-derived clock */
+ else if (clk->flags & CLK_PLL)
+ clk->recalc = clk_sysclk_recalc;
+
+ /* Otherwise, it is a leaf clock (PSC clock) */
+ else if (clk->parent)
+ clk->recalc = clk_leafclk_recalc;
+ }
+
+ if (clk->recalc)
+ clk->rate = clk->recalc(clk);
+
+ clk_register(clk);
+ num_clocks++;
+
+ /* Turn on clocks that Linux doesn't otherwise manage */
+ if (clk->flags & ALWAYS_ENABLED)
+ clk_enable(clk);
+ }
+
+ clkdev_add_table(clocks, num_clocks);
+
+ return 0;
+}
+
+#ifdef CONFIG_DEBUG_FS
+
+#include <linux/debugfs.h>
+#include <linux/seq_file.h>
+
+#define CLKNAME_MAX 10 /* longest clock name */
+#define NEST_DELTA 2
+#define NEST_MAX 4
+
+static void
+dump_clock(struct seq_file *s, unsigned nest, struct clk *parent)
+{
+ char *state;
+ char buf[CLKNAME_MAX + NEST_DELTA * NEST_MAX];
+ struct clk *clk;
+ unsigned i;
+
+ if (parent->flags & CLK_PLL)
+ state = "pll";
+ else
+ state = "";
+
+ /* <nest spaces> name <pad to end> */
+ memset(buf, ' ', sizeof(buf) - 1);
+ buf[sizeof(buf) - 1] = 0;
+ i = strlen(parent->name);
+ memcpy(buf + nest, parent->name,
+ min(i, (unsigned)(sizeof(buf) - 1 - nest)));
+
+ seq_printf(s, "%s users=%2d %-3s %9ld Hz\n",
+ buf, parent->usecount, state, clk_get_rate(parent));
+ /* REVISIT show device associations too */
+
+ /* cost is now small, but not linear... */
+ list_for_each_entry(clk, &parent->children, childnode) {
+ dump_clock(s, nest + NEST_DELTA, clk);
+ }
+}
+
+static int c6x_ck_show(struct seq_file *m, void *v)
+{
+ struct clk *clk;
+
+ /*
+ * Show clock tree; We trust nonzero usecounts equate to PSC enables...
+ */
+ mutex_lock(&clocks_mutex);
+ list_for_each_entry(clk, &clocks, node)
+ if (!clk->parent)
+ dump_clock(m, 0, clk);
+ mutex_unlock(&clocks_mutex);
+
+ return 0;
+}
+
+static int c6x_ck_open(struct inode *inode, struct file *file)
+{
+ return single_open(file, c6x_ck_show, NULL);
+}
+
+static const struct file_operations c6x_ck_operations = {
+ .open = c6x_ck_open,
+ .read = seq_read,
+ .llseek = seq_lseek,
+ .release = single_release,
+};
+
+static int __init c6x_clk_debugfs_init(void)
+{
+ debugfs_create_file("c6x_clocks", S_IFREG | S_IRUGO, NULL, NULL,
+ &c6x_ck_operations);
+
+ return 0;
+}
+device_initcall(c6x_clk_debugfs_init);
+#endif /* CONFIG_DEBUG_FS */
diff --git a/drivers/platform/c6x/timer-tci648x.c b/drivers/platform/c6x/timer-tci648x.c
new file mode 100644
index 0000000..79cda27
--- /dev/null
+++ b/drivers/platform/c6x/timer-tci648x.c
@@ -0,0 +1,121 @@
+/*
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Contributed by: Mark Salter ([email protected])
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clockchips.h>
+#include <linux/interrupt.h>
+#include <linux/percpu.h>
+#include <linux/smp.h>
+#include <linux/io.h>
+#include <linux/bug.h>
+
+#include <asm/irq.h>
+#include <asm/timer.h>
+#include <asm/system.h>
+
+#include <mach/board.h>
+
+#ifdef CONFIG_GENERIC_CLOCKEVENTS
+
+static int next_event(unsigned long delta,
+ struct clock_event_device *evt)
+{
+ u32 timer_CNTLO = TIMER_CNTLO_REG(LINUX_TIMER_SRC);
+ u32 timer_PRDLO = TIMER_PRDLO_REG(LINUX_TIMER_SRC);
+ u32 timer_TCR = TIMER_TCR_REG(LINUX_TIMER_SRC);
+
+ TIMER_REG(timer_TCR) &= ~TIMER_B_TCR_ENAMODELO_MASK;
+ TIMER_REG(timer_PRDLO) = delta - 1;
+ TIMER_REG(timer_CNTLO) = 0;
+ TIMER_REG(timer_TCR) |= TIMER_B_TCR_ENAMODELO_ONCE;
+
+ return 0;
+}
+
+static void set_clock_mode(enum clock_event_mode mode,
+ struct clock_event_device *evt)
+{
+}
+
+static void event_handler(struct clock_event_device *dev)
+{
+}
+
+static struct clock_event_device t64_clockevent_device;
+
+static irqreturn_t timer_interrupt(int irq, void *dev_id)
+{
+ struct clock_event_device *cd = &t64_clockevent_device;
+
+ cd->event_handler(cd);
+
+ return IRQ_HANDLED;
+}
+
+int __init c6x_arch_init_clockevents(void)
+{
+ struct clock_event_device *cd = &t64_clockevent_device;
+ u64 temp;
+ u32 shift, timer_TCR, timer_TGCR;
+ u32 timer_PRDLO, timer_CNTLO, timer_EMUMGTCLKSPD;
+
+ timer_TCR = TIMER_TCR_REG(LINUX_TIMER_SRC);
+ timer_TGCR = TIMER_TGCR_REG(LINUX_TIMER_SRC);
+ timer_CNTLO = TIMER_CNTLO_REG(LINUX_TIMER_SRC);
+ timer_PRDLO = TIMER_PRDLO_REG(LINUX_TIMER_SRC);
+ timer_EMUMGTCLKSPD = TIMER_EMUMGTCLKSPD_REG(LINUX_TIMER_SRC);
+
+ /* disable timer, reset count */
+ TIMER_REG(timer_TCR) &= ~TIMER_B_TCR_ENAMODELO_MASK;
+ TIMER_REG(timer_PRDLO) = 0;
+
+ /* use internal clock and 1 cycle pulse width */
+ TIMER_REG(timer_TCR) &= ~(TIMER_B_TCR_CLKSRCLO | TIMER_B_TCR_PWIDLO_MASK);
+
+ /* dual 32-bit unchained mode */
+ TIMER_REG(timer_TGCR) &= ~TIMER_B_TGCR_TIMMODE_MASK;
+ TIMER_REG(timer_TGCR) |= (TIMER_B_TGCR_TIMLORS | TIMER_B_TGCR_TIMMODE_UD32);
+
+ cd->irq = LINUX_TIMER_IRQ;
+ cd->name = "TIMER64_EVT32_TIMER";
+ cd->features = CLOCK_EVT_FEAT_ONESHOT;
+
+ /* Calculate the min / max delta */
+ /* Find a shift value */
+ for (shift = 32; shift > 0; shift--) {
+ temp = (u64)(c6x_core_freq / TIMER_DIVISOR(LINUX_TIMER_SRC));
+ temp <<= shift;
+
+ do_div(temp, NSEC_PER_SEC);
+ if ((temp >> 32) == 0)
+ break;
+ }
+ cd->shift = shift;
+ cd->mult = (u32) temp;
+
+ cd->max_delta_ns = clockevent_delta2ns(0x7fffffff, cd);
+ cd->min_delta_ns = clockevent_delta2ns(250, cd);
+
+ cd->rating = 200;
+ cd->set_mode = set_clock_mode;
+ cd->event_handler = event_handler;
+ cd->set_next_event = next_event;
+ cd->cpumask = cpumask_of(smp_processor_id());
+
+ clockevents_register_device(cd);
+
+ /* Set handler */
+ request_irq(cd->irq, timer_interrupt, IRQF_DISABLED | IRQF_TIMER,
+ "timer", NULL);
+
+ return 0;
+}
+
+#endif /* CONFIG_GENERIC_CLOCKEVENTS */
+
diff --git a/drivers/platform/c6x/tsc-c64xplus.c b/drivers/platform/c6x/tsc-c64xplus.c
new file mode 100644
index 0000000..437bf25
--- /dev/null
+++ b/drivers/platform/c6x/tsc-c64xplus.c
@@ -0,0 +1,53 @@
+/*
+ * Port on Texas Instruments TMS320C6x architecture
+ *
+ * Copyright (C) 2010 Texas Instruments Incorporated
+ * Contributed by: Mark Salter <[email protected]>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/clocksource.h>
+#include <asm/timer.h>
+
+
+#ifdef CONFIG_GENERIC_TIME
+static cycle_t tsc_read(struct clocksource *cs)
+{
+ return get_cycles();
+}
+
+static struct clocksource clocksource_tsc = {
+ .name = "TSC64",
+ .rating = 300,
+ .read = tsc_read,
+ .mask = CLOCKSOURCE_MASK(64),
+ .flags = CLOCK_SOURCE_IS_CONTINUOUS,
+};
+
+int __init c6x_arch_init_clocksource(void)
+{
+ struct clocksource *cs = &clocksource_tsc;
+ u64 temp;
+ u32 shift;
+
+ /* Find a shift value */
+ for (shift = 32; shift > 0; shift--) {
+ temp = (u64) NSEC_PER_SEC << shift;
+ do_div(temp, c6x_core_freq);
+ if ((temp >> 32) == 0)
+ break;
+ }
+ cs->shift = shift;
+ cs->mult = (u32) temp;
+
+ /* write anything into TSCL to enable counting */
+ set_creg(TSCL, 0);
+
+ clocksource_register(cs);
+
+ return 0;
+}
+#endif /* CONFIG_GENERIC_TIME */
+
--
1.6.2.5

2011-05-11 21:08:08

by Mark Salter

[permalink] [raw]
Subject: [PATCH 14/16] C6X: add default configs

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/configs/ti_dsk6455_defconfig | 970 ++++++++++++++++++++++++++
arch/c6x/configs/ti_evmc6457_defconfig | 980 ++++++++++++++++++++++++++
arch/c6x/configs/ti_evmc6472_defconfig | 982 +++++++++++++++++++++++++++
arch/c6x/configs/ti_evmc6474_defconfig | 966 ++++++++++++++++++++++++++
arch/c6x/configs/ti_evmc6474_lite_defconfig | 980 ++++++++++++++++++++++++++
5 files changed, 4878 insertions(+), 0 deletions(-)
create mode 100644 arch/c6x/configs/ti_dsk6455_defconfig
create mode 100644 arch/c6x/configs/ti_evmc6457_defconfig
create mode 100644 arch/c6x/configs/ti_evmc6472_defconfig
create mode 100644 arch/c6x/configs/ti_evmc6474_defconfig
create mode 100644 arch/c6x/configs/ti_evmc6474_lite_defconfig

diff --git a/arch/c6x/configs/ti_dsk6455_defconfig b/arch/c6x/configs/ti_dsk6455_defconfig
new file mode 100644
index 0000000..3487af4
--- /dev/null
+++ b/arch/c6x/configs/ti_dsk6455_defconfig
@@ -0,0 +1,970 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Fri Jul 30 07:41:30 2010
+#
+CONFIG_TMS320C6X=y
+# CONFIG_MMU is not set
+CONFIG_ZONE_DMA=y
+# CONFIG_SBUS is not set
+# CONFIG_FPU is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_NUMA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_BUG=y
+CONFIG_COMMON_CLKDEV=y
+# CONFIG_BIG_KERNEL is not set
+# CONFIG_XIP_KERNEL is not set
+CONFIG_XIP_KERNEL_TEXT_ADDR=0xE0000000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_XZ is not set
+CONFIG_RD_LZO=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+CONFIG_CMDLINE="console=hvc rw ip=dhcp"
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor type and features
+#
+CONFIG_TMS320C64XPLUS=y
+CONFIG_HVC_C6X=y
+CONFIG_SOC_TMS320C6455=y
+# CONFIG_SOC_TMS320C6457 is not set
+# CONFIG_SOC_TMS320C6472 is not set
+# CONFIG_SOC_TMS320C6474 is not set
+
+#
+# Board Selection
+#
+CONFIG_ARCH_BOARD_DSK6455=y
+# CONFIG_ARCH_BOARD_EVM6457 is not set
+# CONFIG_ARCH_BOARD_EVM6472 is not set
+# CONFIG_ARCH_BOARD_EVM6474 is not set
+# CONFIG_ARCH_BOARD_EVM6474L is not set
+# CONFIG_USE_RT_TIMER is not set
+# CONFIG_SGMII is not set
+CONFIG_TMS320C6X_CACHES_ON=y
+CONFIG_KERNEL_RAM_BASE_ADDRESS=0xe0000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+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=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# Executable file formats
+#
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP 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_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_PARTITIONS=y
+# 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_SM_FTL 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=y
+# CONFIG_MTD_CFI_STAA is not set
+CONFIG_MTD_CFI_UTIL=y
+CONFIG_MTD_RAM=y
+# 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=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=16384
+CONFIG_MTDRAM_ERASE_SIZE=128
+# 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_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=17000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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_MII is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ETHOC 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_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NETDEV_10000=y
+CONFIG_TMS320C64X_GEMAC=y
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# 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
+# CONFIG_INPUT_SPARSEKMAP 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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+# CONFIG_SERIAL_CORE is not set
+# CONFIG_SERIAL_CORE_CONSOLE is not set
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+# CONFIG_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# 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_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_C6X_PLATFORM_DEVICES=y
+CONFIG_PLL_TCI648X=y
+CONFIG_TIMER_TCI648X=y
+CONFIG_PIC_C64XPLUS=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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=m
+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_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+# CONFIG_ROMFS_ON_BLOCK is not set
+# CONFIG_PSTORE 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_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=m
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
+# 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=m
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+# 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# 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_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# 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=m
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_ACCESS_CHECK=y
diff --git a/arch/c6x/configs/ti_evmc6457_defconfig b/arch/c6x/configs/ti_evmc6457_defconfig
new file mode 100644
index 0000000..e18b095
--- /dev/null
+++ b/arch/c6x/configs/ti_evmc6457_defconfig
@@ -0,0 +1,980 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Sun Aug 1 22:59:12 2010
+#
+CONFIG_TMS320C6X=y
+# CONFIG_MMU is not set
+CONFIG_ZONE_DMA=y
+# CONFIG_SBUS is not set
+# CONFIG_FPU is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_NUMA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_BUG=y
+CONFIG_COMMON_CLKDEV=y
+# CONFIG_BIG_KERNEL is not set
+# CONFIG_XIP_KERNEL is not set
+CONFIG_XIP_KERNEL_TEXT_ADDR=0xE0000000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_XZ is not set
+CONFIG_RD_LZO=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+CONFIG_CMDLINE="console=hvc rw ip=dhcp"
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor type and features
+#
+CONFIG_TMS320C64XPLUS=y
+CONFIG_HVC_C6X=y
+# CONFIG_SOC_TMS320C6455 is not set
+CONFIG_SOC_TMS320C6457=y
+# CONFIG_SOC_TMS320C6472 is not set
+# CONFIG_SOC_TMS320C6474 is not set
+
+#
+# Board Selection
+#
+# CONFIG_ARCH_BOARD_DSK6455 is not set
+CONFIG_ARCH_BOARD_EVM6457=y
+# CONFIG_ARCH_BOARD_EVM6472 is not set
+# CONFIG_ARCH_BOARD_EVM6474 is not set
+# CONFIG_ARCH_BOARD_EVM6474L is not set
+# CONFIG_USE_RT_TIMER is not set
+CONFIG_SGMII=y
+CONFIG_TMS320C6X_CACHES_ON=y
+CONFIG_KERNEL_RAM_BASE_ADDRESS=0xe0000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+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=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# Executable file formats
+#
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP 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_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_PARTITIONS=y
+# 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_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# 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=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=y
+# 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=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=16384
+CONFIG_MTDRAM_ERASE_SIZE=128
+# 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_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=17000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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_MII is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ETHOC 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_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NETDEV_10000=y
+CONFIG_TMS320C64X_GEMAC=y
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# 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
+# CONFIG_INPUT_SPARSEKMAP 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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# 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_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_C6X_PLATFORM_DEVICES=y
+CONFIG_PLL_TCI648X=y
+CONFIG_TIMER_TCI648X=y
+CONFIG_PIC_C64XPLUS=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+# CONFIG_ROMFS_ON_BLOCK is not set
+# CONFIG_PSTORE 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_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=m
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
+# 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=m
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+# 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# 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_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_ACCESS_CHECK=y
diff --git a/arch/c6x/configs/ti_evmc6472_defconfig b/arch/c6x/configs/ti_evmc6472_defconfig
new file mode 100644
index 0000000..14ae81b
--- /dev/null
+++ b/arch/c6x/configs/ti_evmc6472_defconfig
@@ -0,0 +1,982 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Sun Aug 1 22:59:12 2010
+#
+CONFIG_TMS320C6X=y
+# CONFIG_MMU is not set
+CONFIG_ZONE_DMA=y
+# CONFIG_SBUS is not set
+# CONFIG_FPU is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_NUMA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_BUG=y
+CONFIG_COMMON_CLKDEV=y
+# CONFIG_BIG_KERNEL is not set
+# CONFIG_XIP_KERNEL is not set
+CONFIG_XIP_KERNEL_TEXT_ADDR=0xE0000000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_XZ is not set
+CONFIG_RD_LZO=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+CONFIG_CMDLINE="console=hvc rw ip=dhcp"
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor type and features
+#
+CONFIG_TMS320C64XPLUS=y
+CONFIG_HVC_C6X=y
+# CONFIG_SOC_TMS320C6455 is not set
+# CONFIG_SOC_TMS320C6457 is not set
+CONFIG_SOC_TMS320C6472=y
+# CONFIG_SOC_TMS320C6474 is not set
+
+#
+# Board Selection
+#
+# CONFIG_ARCH_BOARD_DSK6455 is not set
+# CONFIG_ARCH_BOARD_EVM6457 is not set
+CONFIG_ARCH_BOARD_EVM6472=y
+# CONFIG_ARCH_BOARD_EVM6474 is not set
+# CONFIG_ARCH_BOARD_EVM6474L is not set
+# CONFIG_USE_RT_TIMER is not set
+# CONFIG_SGMII is not set
+CONFIG_TMS320C64X_GEMAC_0=y
+# CONFIG_TMS320C64X_GEMAC_1 is not set
+CONFIG_TMS320C6X_CACHES_ON=y
+CONFIG_KERNEL_RAM_BASE_ADDRESS=0xe0000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+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=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# Executable file formats
+#
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP 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_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_PARTITIONS=y
+# 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_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# 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=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=y
+# 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=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=16384
+CONFIG_MTDRAM_ERASE_SIZE=128
+# 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_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=17000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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_MII is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ETHOC 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_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NETDEV_10000=y
+CONFIG_TMS320C64X_GEMAC=y
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# 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
+# CONFIG_INPUT_SPARSEKMAP 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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# 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_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_C6X_PLATFORM_DEVICES=y
+CONFIG_PLL_TCI648X=y
+CONFIG_TIMER_TCI648X=y
+CONFIG_PIC_C64XPLUS=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+# CONFIG_ROMFS_ON_BLOCK is not set
+# CONFIG_PSTORE 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_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=m
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
+# 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=m
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+# 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# 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_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_ACCESS_CHECK=y
diff --git a/arch/c6x/configs/ti_evmc6474_defconfig b/arch/c6x/configs/ti_evmc6474_defconfig
new file mode 100644
index 0000000..472ad6b
--- /dev/null
+++ b/arch/c6x/configs/ti_evmc6474_defconfig
@@ -0,0 +1,966 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Sun Aug 1 22:59:12 2010
+#
+CONFIG_TMS320C6X=y
+# CONFIG_MMU is not set
+CONFIG_ZONE_DMA=y
+# CONFIG_SBUS is not set
+# CONFIG_FPU is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_NUMA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_BUG=y
+CONFIG_COMMON_CLKDEV=y
+# CONFIG_BIG_KERNEL is not set
+# CONFIG_XIP_KERNEL is not set
+CONFIG_XIP_KERNEL_TEXT_ADDR=0x80000000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_XZ is not set
+CONFIG_RD_LZO=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+CONFIG_CMDLINE="console=hvc rw ip=dhcp"
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor type and features
+#
+CONFIG_TMS320C64XPLUS=y
+CONFIG_HVC_C6X=y
+# CONFIG_SOC_TMS320C6455 is not set
+# CONFIG_SOC_TMS320C6457 is not set
+# CONFIG_SOC_TMS320C6472 is not set
+CONFIG_SOC_TMS320C6474=y
+
+#
+# Board Selection
+#
+# CONFIG_ARCH_BOARD_DSK6455 is not set
+# CONFIG_ARCH_BOARD_EVM6457 is not set
+# CONFIG_ARCH_BOARD_EVM6472 is not set
+CONFIG_ARCH_BOARD_EVM6474=y
+# CONFIG_ARCH_BOARD_EVM6474L is not set
+# CONFIG_USE_RT_TIMER is not set
+CONFIG_SGMII=y
+CONFIG_TMS320C6X_CACHES_ON=y
+CONFIG_KERNEL_RAM_BASE_ADDRESS=0x80000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+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=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# Executable file formats
+#
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP 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_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_PARTITIONS=y
+# 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_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# 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=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=y
+# 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=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=16384
+CONFIG_MTDRAM_ERASE_SIZE=128
+# 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_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=17000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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_MII is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ETHOC 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_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NETDEV_10000=y
+CONFIG_TMS320C64X_GEMAC=y
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# 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
+# CONFIG_INPUT_SPARSEKMAP 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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# 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_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_C6X_PLATFORM_DEVICES=y
+CONFIG_PLL_TCI648X=y
+CONFIG_TIMER_TCI648X=y
+CONFIG_PIC_C64XPLUS=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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 is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+# CONFIG_ROMFS_ON_BLOCK is not set
+# CONFIG_PSTORE 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_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=m
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
+# 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=m
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+# 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# 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_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_ACCESS_CHECK=y
diff --git a/arch/c6x/configs/ti_evmc6474_lite_defconfig b/arch/c6x/configs/ti_evmc6474_lite_defconfig
new file mode 100644
index 0000000..e25e8ac
--- /dev/null
+++ b/arch/c6x/configs/ti_evmc6474_lite_defconfig
@@ -0,0 +1,980 @@
+#
+# Automatically generated make config: don't edit
+# Linux kernel version: 2.6.34
+# Sun Aug 1 22:59:12 2010
+#
+CONFIG_TMS320C6X=y
+# CONFIG_MMU is not set
+CONFIG_ZONE_DMA=y
+# CONFIG_SBUS is not set
+# CONFIG_FPU is not set
+# CONFIG_HIGHMEM is not set
+# CONFIG_NUMA is not set
+CONFIG_RWSEM_GENERIC_SPINLOCK=y
+# CONFIG_RWSEM_XCHGADD_ALGORITHM is not set
+CONFIG_GENERIC_CALIBRATE_DELAY=y
+CONFIG_GENERIC_HWEIGHT=y
+CONFIG_GENERIC_TIME=y
+CONFIG_GENERIC_CLOCKEVENTS=y
+CONFIG_GENERIC_CLOCKEVENTS_BUILD=y
+CONFIG_GENERIC_BUG=y
+CONFIG_COMMON_CLKDEV=y
+# CONFIG_BIG_KERNEL is not set
+# CONFIG_XIP_KERNEL is not set
+CONFIG_XIP_KERNEL_TEXT_ADDR=0x80000000
+CONFIG_DEFCONFIG_LIST="/lib/modules/$UNAME_RELEASE/.config"
+CONFIG_CONSTRUCTORS=y
+
+#
+# General setup
+#
+CONFIG_EXPERIMENTAL=y
+CONFIG_BROKEN_ON_SMP=y
+CONFIG_INIT_ENV_ARG_LIMIT=32
+CONFIG_CROSS_COMPILE=""
+CONFIG_LOCALVERSION=""
+# CONFIG_LOCALVERSION_AUTO is not set
+CONFIG_SYSVIPC=y
+CONFIG_SYSVIPC_SYSCTL=y
+CONFIG_POSIX_MQUEUE=y
+CONFIG_POSIX_MQUEUE_SYSCTL=y
+# CONFIG_BSD_PROCESS_ACCT is not set
+# CONFIG_FHANDLE is not set
+# CONFIG_TASKSTATS is not set
+# CONFIG_AUDIT is not set
+CONFIG_HAVE_GENERIC_HARDIRQS=y
+
+#
+# IRQ subsystem
+#
+CONFIG_GENERIC_HARDIRQS=y
+
+#
+# RCU Subsystem
+#
+CONFIG_TINY_RCU=y
+# CONFIG_PREEMPT_RCU is not set
+# CONFIG_RCU_TRACE is not set
+# CONFIG_TREE_RCU_TRACE is not set
+# CONFIG_IKCONFIG is not set
+CONFIG_LOG_BUF_SHIFT=14
+# CONFIG_CGROUPS is not set
+CONFIG_NAMESPACES=y
+# CONFIG_UTS_NS is not set
+CONFIG_IPC_NS=y
+# CONFIG_USER_NS is not set
+# CONFIG_PID_NS is not set
+# CONFIG_NET_NS is not set
+# CONFIG_SCHED_AUTOGROUP is not set
+# CONFIG_SYSFS_DEPRECATED is not set
+# CONFIG_RELAY is not set
+CONFIG_BLK_DEV_INITRD=y
+CONFIG_INITRAMFS_SOURCE=""
+CONFIG_INITRAMFS_ROOT_UID=0
+CONFIG_INITRAMFS_ROOT_GID=0
+CONFIG_RD_GZIP=y
+CONFIG_RD_BZIP2=y
+CONFIG_RD_LZMA=y
+# CONFIG_RD_XZ is not set
+CONFIG_RD_LZO=y
+# CONFIG_INITRAMFS_COMPRESSION_NONE is not set
+# CONFIG_INITRAMFS_COMPRESSION_GZIP is not set
+# CONFIG_INITRAMFS_COMPRESSION_BZIP2 is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZMA is not set
+# CONFIG_INITRAMFS_COMPRESSION_LZO is not set
+CONFIG_CC_OPTIMIZE_FOR_SIZE=y
+CONFIG_SYSCTL=y
+CONFIG_ANON_INODES=y
+CONFIG_EXPERT=y
+CONFIG_SYSCTL_SYSCALL=y
+CONFIG_KALLSYMS=y
+# CONFIG_KALLSYMS_EXTRA_PASS is not set
+CONFIG_HOTPLUG=y
+CONFIG_PRINTK=y
+CONFIG_BUG=y
+CONFIG_ELF_CORE=y
+CONFIG_BASE_FULL=y
+CONFIG_FUTEX=y
+CONFIG_EPOLL=y
+CONFIG_SIGNALFD=y
+CONFIG_TIMERFD=y
+CONFIG_EVENTFD=y
+CONFIG_AIO=y
+CONFIG_EMBEDDED=y
+
+#
+# Kernel Performance Events And Counters
+#
+CONFIG_VM_EVENT_COUNTERS=y
+# CONFIG_SLUB_DEBUG is not set
+CONFIG_COMPAT_BRK=y
+# CONFIG_SLAB is not set
+CONFIG_SLUB=y
+# CONFIG_SLOB is not set
+# CONFIG_MMAP_ALLOW_UNINITIALIZED is not set
+# CONFIG_PROFILING is not set
+
+#
+# GCOV-based kernel profiling
+#
+# CONFIG_HAVE_GENERIC_DMA_COHERENT is not set
+CONFIG_RT_MUTEXES=y
+CONFIG_BASE_SMALL=0
+CONFIG_MODULES=y
+CONFIG_MODULE_FORCE_LOAD=y
+CONFIG_MODULE_UNLOAD=y
+CONFIG_MODULE_FORCE_UNLOAD=y
+# CONFIG_MODVERSIONS is not set
+# CONFIG_MODULE_SRCVERSION_ALL is not set
+CONFIG_BLOCK=y
+CONFIG_LBDAF=y
+CONFIG_BLK_DEV_BSG=y
+# CONFIG_BLK_DEV_INTEGRITY is not set
+
+#
+# IO Schedulers
+#
+CONFIG_IOSCHED_NOOP=y
+CONFIG_IOSCHED_DEADLINE=y
+CONFIG_IOSCHED_CFQ=y
+# CONFIG_DEFAULT_DEADLINE is not set
+CONFIG_DEFAULT_CFQ=y
+# CONFIG_DEFAULT_NOOP is not set
+CONFIG_DEFAULT_IOSCHED="cfq"
+# CONFIG_INLINE_SPIN_TRYLOCK is not set
+# CONFIG_INLINE_SPIN_TRYLOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK is not set
+# CONFIG_INLINE_SPIN_LOCK_BH is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQ is not set
+# CONFIG_INLINE_SPIN_LOCK_IRQSAVE is not set
+CONFIG_INLINE_SPIN_UNLOCK=y
+# CONFIG_INLINE_SPIN_UNLOCK_BH is not set
+CONFIG_INLINE_SPIN_UNLOCK_IRQ=y
+# CONFIG_INLINE_SPIN_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_READ_TRYLOCK is not set
+# CONFIG_INLINE_READ_LOCK is not set
+# CONFIG_INLINE_READ_LOCK_BH is not set
+# CONFIG_INLINE_READ_LOCK_IRQ is not set
+# CONFIG_INLINE_READ_LOCK_IRQSAVE is not set
+CONFIG_INLINE_READ_UNLOCK=y
+# CONFIG_INLINE_READ_UNLOCK_BH is not set
+CONFIG_INLINE_READ_UNLOCK_IRQ=y
+# CONFIG_INLINE_READ_UNLOCK_IRQRESTORE is not set
+# CONFIG_INLINE_WRITE_TRYLOCK is not set
+# CONFIG_INLINE_WRITE_LOCK is not set
+# CONFIG_INLINE_WRITE_LOCK_BH is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQ is not set
+# CONFIG_INLINE_WRITE_LOCK_IRQSAVE is not set
+CONFIG_INLINE_WRITE_UNLOCK=y
+# CONFIG_INLINE_WRITE_UNLOCK_BH is not set
+CONFIG_INLINE_WRITE_UNLOCK_IRQ=y
+# CONFIG_INLINE_WRITE_UNLOCK_IRQRESTORE is not set
+# CONFIG_MUTEX_SPIN_ON_OWNER is not set
+# CONFIG_FREEZER is not set
+CONFIG_CMDLINE="console=hvc rw ip=dhcp"
+# CONFIG_CPU_BIG_ENDIAN is not set
+CONFIG_FORCE_MAX_ZONEORDER=13
+
+#
+# Processor type and features
+#
+CONFIG_TMS320C64XPLUS=y
+CONFIG_HVC_C6X=y
+# CONFIG_SOC_TMS320C6455 is not set
+# CONFIG_SOC_TMS320C6457 is not set
+# CONFIG_SOC_TMS320C6472 is not set
+CONFIG_SOC_TMS320C6474=y
+
+#
+# Board Selection
+#
+# CONFIG_ARCH_BOARD_DSK6455 is not set
+# CONFIG_ARCH_BOARD_EVM6457 is not set
+# CONFIG_ARCH_BOARD_EVM6472 is not set
+# CONFIG_ARCH_BOARD_EVM6474 is not set
+CONFIG_ARCH_BOARD_EVM6474L=y
+# CONFIG_USE_RT_TIMER is not set
+CONFIG_SGMII=y
+CONFIG_TMS320C6X_CACHES_ON=y
+CONFIG_KERNEL_RAM_BASE_ADDRESS=0x80000000
+CONFIG_SELECT_MEMORY_MODEL=y
+CONFIG_FLATMEM_MANUAL=y
+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=1
+CONFIG_VIRT_TO_BUS=y
+CONFIG_NOMMU_INITIAL_TRIM_EXCESS=1
+CONFIG_NEED_PER_CPU_KM=y
+CONFIG_PREEMPT_NONE=y
+# CONFIG_PREEMPT_VOLUNTARY is not set
+# CONFIG_PREEMPT is not set
+# CONFIG_HZ_100 is not set
+CONFIG_HZ_250=y
+# CONFIG_HZ_300 is not set
+# CONFIG_HZ_1000 is not set
+CONFIG_HZ=250
+CONFIG_SCHED_HRTICK=y
+CONFIG_TICK_ONESHOT=y
+CONFIG_NO_HZ=y
+CONFIG_HIGH_RES_TIMERS=y
+
+#
+# Bus options (PCI, PCMCIA, EISA, MCA, ISA)
+#
+# CONFIG_PCI is not set
+
+#
+# Executable file formats
+#
+# CONFIG_BINFMT_FLAT is not set
+# CONFIG_HAVE_AOUT is not set
+# CONFIG_BINFMT_MISC is not set
+
+#
+# Power management options
+#
+# CONFIG_PM is not set
+CONFIG_NET=y
+
+#
+# Networking options
+#
+CONFIG_PACKET=y
+CONFIG_UNIX=y
+# CONFIG_NET_KEY is not set
+CONFIG_INET=y
+CONFIG_IP_MULTICAST=y
+# CONFIG_IP_ADVANCED_ROUTER is not set
+CONFIG_IP_PNP=y
+CONFIG_IP_PNP_DHCP=y
+CONFIG_IP_PNP_BOOTP=y
+CONFIG_IP_PNP_RARP=y
+# CONFIG_NET_IPIP is not set
+# CONFIG_NET_IPGRE_DEMUX 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=y
+CONFIG_INET_DIAG=y
+CONFIG_INET_TCP_DIAG=y
+# 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_NETWORK_PHY_TIMESTAMPING is not set
+# CONFIG_NETFILTER is not set
+# CONFIG_IP_DCCP is not set
+# CONFIG_IP_SCTP is not set
+# CONFIG_RDS is not set
+# CONFIG_TIPC is not set
+# CONFIG_ATM is not set
+# CONFIG_L2TP 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_PHONET is not set
+# CONFIG_IEEE802154 is not set
+# CONFIG_NET_SCHED is not set
+# CONFIG_DCB is not set
+# CONFIG_BATMAN_ADV 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_WIRELESS=y
+# CONFIG_CFG80211 is not set
+# CONFIG_LIB80211 is not set
+
+#
+# CFG80211 needs to be enabled for MAC80211
+#
+# CONFIG_WIMAX is not set
+# CONFIG_RFKILL is not set
+# CONFIG_NET_9P is not set
+# CONFIG_CAIF is not set
+# CONFIG_CEPH_LIB is not set
+
+#
+# Device Drivers
+#
+
+#
+# Generic Driver Options
+#
+CONFIG_UEVENT_HELPER_PATH=""
+# CONFIG_DEVTMPFS is not set
+CONFIG_STANDALONE=y
+CONFIG_PREVENT_FIRMWARE_BUILD=y
+CONFIG_FW_LOADER=y
+CONFIG_FIRMWARE_IN_KERNEL=y
+CONFIG_EXTRA_FIRMWARE=""
+# CONFIG_SYS_HYPERVISOR is not set
+# CONFIG_CONNECTOR is not set
+CONFIG_MTD=y
+# CONFIG_MTD_DEBUG is not set
+# CONFIG_MTD_TESTS is not set
+CONFIG_MTD_PARTITIONS=y
+# 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_SM_FTL is not set
+# CONFIG_MTD_OOPS is not set
+
+#
+# RAM/ROM/Flash chip drivers
+#
+CONFIG_MTD_CFI=m
+CONFIG_MTD_JEDECPROBE=m
+CONFIG_MTD_GEN_PROBE=m
+# 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=m
+CONFIG_MTD_CFI_AMDSTD=m
+CONFIG_MTD_CFI_STAA=m
+CONFIG_MTD_CFI_UTIL=m
+CONFIG_MTD_RAM=y
+# 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=m
+# CONFIG_MTD_PHYSMAP_COMPAT is not set
+CONFIG_MTD_UCLINUX=y
+CONFIG_MTD_PLATRAM=y
+
+#
+# Self-contained MTD device drivers
+#
+# CONFIG_MTD_SLRAM is not set
+# CONFIG_MTD_PHRAM is not set
+CONFIG_MTD_MTDRAM=m
+CONFIG_MTDRAM_TOTAL_SIZE=16384
+CONFIG_MTDRAM_ERASE_SIZE=128
+# 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_ECC=y
+# CONFIG_MTD_NAND_ECC_SMC is not set
+CONFIG_MTD_NAND=y
+# CONFIG_MTD_NAND_VERIFY_WRITE is not set
+# CONFIG_MTD_NAND_ECC_BCH is not set
+# CONFIG_MTD_SM_COMMON is not set
+# CONFIG_MTD_NAND_MUSEUM_IDS is not set
+CONFIG_MTD_NAND_IDS=y
+# CONFIG_MTD_NAND_DISKONCHIP is not set
+# CONFIG_MTD_NAND_NANDSIM is not set
+# CONFIG_MTD_NAND_PLATFORM is not set
+# CONFIG_MTD_ONENAND is not set
+
+#
+# LPDDR flash memory drivers
+#
+# CONFIG_MTD_LPDDR is not set
+# 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
+
+#
+# DRBD disabled because PROC_FS, INET or CONNECTOR not selected
+#
+# CONFIG_BLK_DEV_NBD is not set
+CONFIG_BLK_DEV_RAM=y
+CONFIG_BLK_DEV_RAM_COUNT=2
+CONFIG_BLK_DEV_RAM_SIZE=17000
+# CONFIG_BLK_DEV_XIP is not set
+# CONFIG_CDROM_PKTCDVD is not set
+# CONFIG_ATA_OVER_ETH is not set
+# CONFIG_BLK_DEV_RBD is not set
+# CONFIG_SENSORS_LIS3LV02D is not set
+# CONFIG_MISC_DEVICES is not set
+
+#
+# SCSI device support
+#
+CONFIG_SCSI_MOD=y
+# 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_MII is not set
+# CONFIG_PHYLIB is not set
+CONFIG_NET_ETHERNET=y
+# CONFIG_ETHOC 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_KS8851_MLL is not set
+CONFIG_NETDEV_1000=y
+# CONFIG_STMMAC_ETH is not set
+CONFIG_NETDEV_10000=y
+CONFIG_TMS320C64X_GEMAC=y
+CONFIG_WLAN=y
+# CONFIG_HOSTAP is not set
+
+#
+# Enable WiMAX (Networking options) to see the WiMAX drivers
+#
+# CONFIG_WAN is not set
+
+#
+# CAIF transport drivers
+#
+# CONFIG_PPP is not set
+# CONFIG_SLIP is not set
+CONFIG_NETCONSOLE=y
+CONFIG_NETPOLL=y
+# CONFIG_NETPOLL_TRAP is not set
+CONFIG_NET_POLL_CONTROLLER=y
+# 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
+# CONFIG_INPUT_SPARSEKMAP 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_UNIX98_PTYS=y
+# CONFIG_DEVPTS_MULTIPLE_INSTANCES is not set
+CONFIG_LEGACY_PTYS=y
+CONFIG_LEGACY_PTY_COUNT=256
+# CONFIG_SERIAL_NONSTANDARD is not set
+# CONFIG_N_GSM is not set
+CONFIG_DEVKMEM=y
+
+#
+# Serial drivers
+#
+# CONFIG_SERIAL_8250 is not set
+
+#
+# Non-8250 serial port support
+#
+CONFIG_SERIAL_CORE=y
+# CONFIG_SERIAL_TIMBERDALE is not set
+# CONFIG_SERIAL_ALTERA_JTAGUART is not set
+# CONFIG_SERIAL_ALTERA_UART is not set
+# CONFIG_TTY_PRINTK is not set
+# CONFIG_IPMI_HANDLER is not set
+CONFIG_HW_RANDOM=y
+# CONFIG_HW_RANDOM_TIMERIOMEM is not set
+# CONFIG_RTC is not set
+# CONFIG_GEN_RTC is not set
+# CONFIG_R3964 is not set
+
+#
+# PCMCIA character devices
+#
+# CONFIG_RAW_DRIVER is not set
+# CONFIG_TCG_TPM is not set
+# CONFIG_RAMOOPS is not set
+# CONFIG_I2C is not set
+# CONFIG_SPI is not set
+
+#
+# PPS support
+#
+# CONFIG_PPS is not set
+
+#
+# PPS generators support
+#
+# CONFIG_W1 is not set
+# CONFIG_POWER_SUPPLY is not set
+# CONFIG_HWMON is not set
+# CONFIG_THERMAL is not set
+CONFIG_WATCHDOG=y
+# CONFIG_WATCHDOG_NOWAYOUT is not set
+
+#
+# Watchdog Device Drivers
+#
+# CONFIG_SOFT_WATCHDOG is not set
+CONFIG_SSB_POSSIBLE=y
+
+#
+# Sonics Silicon Backplane
+#
+# CONFIG_SSB is not set
+CONFIG_MFD_SUPPORT=y
+# 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_ABX500_CORE is not set
+# CONFIG_REGULATOR is not set
+# CONFIG_MEDIA_SUPPORT 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_NFC_DEVICES is not set
+# CONFIG_ACCESSIBILITY is not set
+# CONFIG_RTC_CLASS is not set
+# CONFIG_DMADEVICES is not set
+# CONFIG_AUXDISPLAY is not set
+# CONFIG_UIO is not set
+# CONFIG_STAGING is not set
+CONFIG_C6X_PLATFORM_DEVICES=y
+CONFIG_PLL_TCI648X=y
+CONFIG_TIMER_TCI648X=y
+CONFIG_PIC_C64XPLUS=y
+
+#
+# File systems
+#
+CONFIG_EXT2_FS=y
+# CONFIG_EXT2_FS_XATTR is not set
+CONFIG_EXT3_FS=m
+# CONFIG_EXT3_DEFAULTS_TO_ORDERED is not set
+# CONFIG_EXT3_FS_XATTR is not set
+# CONFIG_EXT4_FS is not set
+CONFIG_JBD=m
+# CONFIG_REISERFS_FS is not set
+# CONFIG_JFS_FS is not set
+# CONFIG_XFS_FS is not set
+# CONFIG_GFS2_FS is not set
+# CONFIG_BTRFS_FS is not set
+# CONFIG_NILFS2_FS is not set
+# CONFIG_FS_POSIX_ACL is not set
+CONFIG_FILE_LOCKING=y
+CONFIG_FSNOTIFY=y
+CONFIG_DNOTIFY=y
+CONFIG_INOTIFY_USER=y
+# CONFIG_FANOTIFY is not set
+# CONFIG_QUOTA is not set
+# CONFIG_QUOTACTL is not set
+# CONFIG_AUTOFS4_FS is not set
+# CONFIG_FUSE_FS is not set
+
+#
+# Caches
+#
+# CONFIG_FSCACHE is not set
+
+#
+# CD-ROM/DVD Filesystems
+#
+CONFIG_ISO9660_FS=m
+# CONFIG_JOLIET is not set
+# CONFIG_ZISOFS is not set
+# CONFIG_UDF_FS is not set
+
+#
+# DOS/FAT/NT Filesystems
+#
+CONFIG_FAT_FS=m
+# CONFIG_MSDOS_FS is not set
+CONFIG_VFAT_FS=m
+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_SYSCTL=y
+CONFIG_SYSFS=y
+# 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=y
+# CONFIG_JFFS2_FS_XATTR is not set
+CONFIG_JFFS2_COMPRESSION_OPTIONS=y
+CONFIG_JFFS2_ZLIB=y
+CONFIG_JFFS2_LZO=y
+CONFIG_JFFS2_RTIME=y
+# CONFIG_JFFS2_RUBIN is not set
+# CONFIG_JFFS2_CMODE_NONE is not set
+CONFIG_JFFS2_CMODE_PRIORITY=y
+# CONFIG_JFFS2_CMODE_SIZE is not set
+# CONFIG_JFFS2_CMODE_FAVOURLZO is not set
+# CONFIG_LOGFS is not set
+CONFIG_CRAMFS=y
+# 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=y
+# CONFIG_ROMFS_BACKED_BY_BLOCK is not set
+CONFIG_ROMFS_BACKED_BY_MTD=y
+# CONFIG_ROMFS_BACKED_BY_BOTH is not set
+# CONFIG_ROMFS_ON_BLOCK is not set
+# CONFIG_PSTORE 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_ROOT_NFS=y
+# CONFIG_NFSD is not set
+CONFIG_LOCKD=y
+CONFIG_LOCKD_V4=y
+CONFIG_NFS_COMMON=y
+CONFIG_SUNRPC=y
+# CONFIG_CEPH_FS is not set
+CONFIG_CIFS=m
+# CONFIG_CIFS_STATS is not set
+# CONFIG_CIFS_WEAK_PW_HASH is not set
+# CONFIG_CIFS_XATTR is not set
+# CONFIG_CIFS_DEBUG2 is not set
+# CONFIG_CIFS_EXPERIMENTAL 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=m
+CONFIG_NLS_DEFAULT="iso8859-1"
+CONFIG_NLS_CODEPAGE_437=m
+# 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=m
+# 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
+
+#
+# Security options
+#
+# CONFIG_KEYS is not set
+# CONFIG_SECURITY_DMESG_RESTRICT is not set
+# CONFIG_SECURITY is not set
+# CONFIG_SECURITYFS is not set
+CONFIG_DEFAULT_SECURITY_DAC=y
+CONFIG_DEFAULT_SECURITY=""
+CONFIG_CRYPTO=m
+
+#
+# Crypto core or helper
+#
+CONFIG_CRYPTO_ALGAPI=m
+CONFIG_CRYPTO_ALGAPI2=m
+CONFIG_CRYPTO_AEAD2=m
+CONFIG_CRYPTO_BLKCIPHER2=m
+CONFIG_CRYPTO_HASH=m
+CONFIG_CRYPTO_HASH2=m
+CONFIG_CRYPTO_RNG=m
+CONFIG_CRYPTO_RNG2=m
+CONFIG_CRYPTO_PCOMP2=m
+CONFIG_CRYPTO_MANAGER=m
+CONFIG_CRYPTO_MANAGER2=m
+CONFIG_CRYPTO_MANAGER_DISABLE_TESTS=y
+# CONFIG_CRYPTO_GF128MUL is not set
+# CONFIG_CRYPTO_NULL is not set
+CONFIG_CRYPTO_WORKQUEUE=m
+# 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=m
+# CONFIG_CRYPTO_XCBC is not set
+# CONFIG_CRYPTO_VMAC is not set
+
+#
+# Digest
+#
+# CONFIG_CRYPTO_CRC32C is not set
+# CONFIG_CRYPTO_GHASH is not set
+CONFIG_CRYPTO_MD4=m
+CONFIG_CRYPTO_MD5=m
+# 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=m
+# CONFIG_CRYPTO_ANUBIS is not set
+CONFIG_CRYPTO_ARC4=m
+# 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_ZLIB is not set
+# CONFIG_CRYPTO_LZO is not set
+
+#
+# Random Number Generation
+#
+CONFIG_CRYPTO_ANSI_CPRNG=m
+# CONFIG_CRYPTO_USER_API_HASH is not set
+# CONFIG_CRYPTO_USER_API_SKCIPHER is not set
+# CONFIG_CRYPTO_HW is not set
+# CONFIG_BINARY_PRINTF is not set
+
+#
+# Library routines
+#
+CONFIG_BITREVERSE=y
+# CONFIG_CRC_CCITT is not set
+CONFIG_CRC16=y
+# 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_LZO_COMPRESS=y
+CONFIG_LZO_DECOMPRESS=y
+# CONFIG_XZ_DEC is not set
+# CONFIG_XZ_DEC_BCJ is not set
+CONFIG_DECOMPRESS_GZIP=y
+CONFIG_DECOMPRESS_BZIP2=y
+CONFIG_DECOMPRESS_LZMA=y
+CONFIG_DECOMPRESS_LZO=y
+CONFIG_HAS_IOMEM=y
+CONFIG_HAS_IOPORT=y
+CONFIG_HAS_DMA=y
+CONFIG_NLATTR=y
+# CONFIG_AVERAGE is not set
+
+#
+# Kernel hacking
+#
+# CONFIG_PRINTK_TIME is not set
+CONFIG_DEFAULT_MESSAGE_LOGLEVEL=4
+CONFIG_ENABLE_WARN_DEPRECATED=y
+# CONFIG_ENABLE_MUST_CHECK is not set
+CONFIG_FRAME_WARN=1024
+# CONFIG_MAGIC_SYSRQ is not set
+# CONFIG_STRIP_ASM_SYMS is not set
+# CONFIG_UNUSED_SYMBOLS is not set
+# CONFIG_DEBUG_FS is not set
+# CONFIG_HEADERS_CHECK is not set
+# CONFIG_DEBUG_SECTION_MISMATCH is not set
+# CONFIG_DEBUG_KERNEL is not set
+# CONFIG_HARDLOCKUP_DETECTOR is not set
+# CONFIG_SLUB_STATS is not set
+# CONFIG_SPARSE_RCU_POINTER is not set
+CONFIG_DEBUG_BUGVERBOSE=y
+CONFIG_DEBUG_MEMORY_INIT=y
+# CONFIG_SYSCTL_SYSCALL_CHECK is not set
+# CONFIG_ATOMIC64_SELFTEST is not set
+# CONFIG_SAMPLES is not set
+# CONFIG_TEST_KSTRTOX is not set
+CONFIG_EARLY_PRINTK=y
+CONFIG_ACCESS_CHECK=y
--
1.6.2.5

2011-05-11 21:08:43

by Mark Salter

[permalink] [raw]
Subject: [PATCH 15/16] Add new elf binfmt support for DSBT

This patch adds support for a new ELF-based binary format for systems without
an MMU. DSBT stands for Data Segment Base Table and supports shared text
segments while allowing for non-shared data. In this regard, it is similar to
FDPIC, but differs in approach. FDPIC ties data segment references to function
pointers and doubles the size of function pointers in doing so. DSBT handles
function pointers in the normal way, but data accesses are performed relative
to a dedicated register pointing to the correct data segment. FDPIC callers are
responsible for setting up the correct data reference before calling a function
in another DSO. With DSBT, the callee is responsible for setting up the correct
data segment pointer.

This format was developed by Texas Instruments for use by their C6X family of
DSPs. However, this patch is not specific to TI DSPs and could be supported
by other architectures.

Signed-off-by: Mark Salter <[email protected]>
---
fs/Kconfig.binfmt | 10 +
fs/Makefile | 1 +
fs/binfmt_elf_dsbt.c | 1035 ++++++++++++++++++++++++++++++++++++++++++++++
include/linux/elf-dsbt.h | 88 ++++
4 files changed, 1134 insertions(+), 0 deletions(-)
create mode 100644 fs/binfmt_elf_dsbt.c
create mode 100644 include/linux/elf-dsbt.h

diff --git a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
index 79e2ca7..8fc5337 100644
--- a/fs/Kconfig.binfmt
+++ b/fs/Kconfig.binfmt
@@ -40,6 +40,16 @@ config BINFMT_ELF_FDPIC

It is also possible to run FDPIC ELF binaries on MMU linux also.

+config BINFMT_ELF_DSBT
+ bool "Kernel support for DSBT ELF binaries"
+ default y
+ depends on (TMS320C6X && !MMU)
+ help
+ ELF DSBT binaries are based on ELF and are similar to FDPIC in that
+ individual load segments can be placed independently of each other.
+ Also like FDPIC, DSBT is designed to allow systems with no MMU to
+ share text segments while data segments are not.
+
config CORE_DUMP_DEFAULT_ELF_HEADERS
bool "Write ELF core dumps with partial segments"
default y
diff --git a/fs/Makefile b/fs/Makefile
index fb68c2b..95c500b 100644
--- a/fs/Makefile
+++ b/fs/Makefile
@@ -40,6 +40,7 @@ obj-y += binfmt_script.o
obj-$(CONFIG_BINFMT_ELF) += binfmt_elf.o
obj-$(CONFIG_COMPAT_BINFMT_ELF) += compat_binfmt_elf.o
obj-$(CONFIG_BINFMT_ELF_FDPIC) += binfmt_elf_fdpic.o
+obj-$(CONFIG_BINFMT_ELF_DSBT) += binfmt_elf_dsbt.o
obj-$(CONFIG_BINFMT_SOM) += binfmt_som.o
obj-$(CONFIG_BINFMT_FLAT) += binfmt_flat.o

diff --git a/fs/binfmt_elf_dsbt.c b/fs/binfmt_elf_dsbt.c
new file mode 100644
index 0000000..24c2b7b
--- /dev/null
+++ b/fs/binfmt_elf_dsbt.c
@@ -0,0 +1,1035 @@
+/* binfmt_elf_dsbt.c: DSBT ELF binary format
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Written by Mark Salter ([email protected])
+ * Derived from binfmt_elf_fdpic.c
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/stat.h>
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/mman.h>
+#include <linux/errno.h>
+#include <linux/signal.h>
+#include <linux/binfmts.h>
+#include <linux/string.h>
+#include <linux/file.h>
+#include <linux/fcntl.h>
+#include <linux/slab.h>
+#include <linux/pagemap.h>
+#include <linux/security.h>
+#include <linux/highmem.h>
+#include <linux/highuid.h>
+#include <linux/personality.h>
+#include <linux/ptrace.h>
+#include <linux/init.h>
+#include <linux/elf.h>
+#include <linux/elf-dsbt.h>
+#include <linux/elfcore.h>
+#include <linux/coredump.h>
+#include <linux/uaccess.h>
+#include <linux/param.h>
+#include <asm/pgalloc.h>
+
+typedef char *elf_caddr_t;
+
+#if 0
+#define kdebug(fmt, ...) printk(KERN_DEBUG "DSBT: "fmt"\n" , ##__VA_ARGS__)
+#else
+#define kdebug(fmt, ...) do {} while (0)
+#endif
+
+#if ELF_EXEC_PAGESIZE > PAGE_SIZE
+#define ELF_MIN_ALIGN ELF_EXEC_PAGESIZE
+#else
+#define ELF_MIN_ALIGN PAGE_SIZE
+#endif
+
+#if ELF_CLASS == ELFCLASS32
+#define dt_tag_t Elf32_Sword
+#define elf_off Elf32_Off
+#else
+#define dt_tag_t Elf64_Sxword
+#define elf_off Elf64_Off
+#endif
+
+
+#define ELF_PAGESTART(_v) ((_v) & ~(unsigned long)(ELF_MIN_ALIGN-1))
+#define ELF_PAGEOFFSET(_v) ((_v) & (ELF_MIN_ALIGN-1))
+#define ELF_PAGEALIGN(_v) (((_v) + ELF_MIN_ALIGN - 1) & ~(ELF_MIN_ALIGN - 1))
+
+#define BAD_ADDR(x) ((unsigned long)(x) >= TASK_SIZE)
+
+static int load_elf_dsbt_binary(struct linux_binprm *, struct pt_regs *);
+
+static struct linux_binfmt elf_dsbt_format = {
+ .module = THIS_MODULE,
+ .load_binary = load_elf_dsbt_binary,
+ .min_coredump = ELF_EXEC_PAGESIZE,
+};
+
+static int is_elf_dsbt(struct elfhdr *hdr, struct file *file)
+{
+ if (memcmp(hdr->e_ident, ELFMAG, SELFMAG) != 0)
+ return 0;
+ if (hdr->e_type != ET_EXEC && hdr->e_type != ET_DYN)
+ return 0;
+ if (!elf_check_arch(hdr) || !elf_check_dsbt(hdr))
+ return 0;
+ if (!file->f_op || !file->f_op->mmap)
+ return 0;
+ return 1;
+}
+
+/*
+ * read the program headers table into memory
+ */
+static int elf_dsbt_fetch_phdrs(struct elf_dsbt_params *params,
+ struct file *file)
+{
+ struct elf32_phdr *phdr;
+ unsigned long size;
+ int retval, loop;
+
+ if (params->hdr.e_phentsize != sizeof(struct elf_phdr))
+ return -ENOMEM;
+ if (params->hdr.e_phnum > 65536U / sizeof(struct elf_phdr))
+ return -ENOMEM;
+
+ size = params->hdr.e_phnum * sizeof(struct elf_phdr);
+ params->phdrs = kmalloc(size, GFP_KERNEL);
+ if (!params->phdrs)
+ return -ENOMEM;
+
+ retval = kernel_read(file, params->hdr.e_phoff,
+ (char *) params->phdrs, size);
+ if (unlikely(retval != size))
+ return retval < 0 ? retval : -ENOEXEC;
+
+ /* determine stack size for this binary */
+ phdr = params->phdrs;
+ for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+ if (phdr->p_type != PT_GNU_STACK)
+ continue;
+
+ params->stack_size = phdr->p_memsz;
+ break;
+ }
+
+ return 0;
+}
+
+/*
+ * read the .dynamic section into memory
+ */
+static int elf_dsbt_fetch_dynamic(struct elf_dsbt_params *params,
+ struct file *file)
+{
+ struct elf_shdr *shdrs, *shdr;
+ int i, retval;
+ unsigned long size;
+
+ if (params->hdr.e_shentsize != sizeof(struct elf_shdr))
+ return -EINVAL;
+ if (params->hdr.e_shnum > 65536U / sizeof(struct elf_shdr))
+ return -EINVAL;
+
+ size = params->hdr.e_shnum * sizeof(struct elf_shdr);
+ shdrs = kmalloc(size, GFP_KERNEL);
+ if (!shdrs)
+ return -ENOMEM;
+
+ retval = kernel_read(file, params->hdr.e_shoff,
+ (char *) shdrs, size);
+ if (unlikely(retval != size)) {
+ kfree(shdrs);
+ return (retval < 0) ? retval : -EIO;
+ }
+
+ shdr = &shdrs[1];
+ for (i = 1; i < params->hdr.e_shnum; i++, shdr++) {
+ if (shdr->sh_type != SHT_DYNAMIC)
+ continue;
+
+ params->dynamic = kmalloc(shdr->sh_size, GFP_KERNEL);
+ if (!params->dynamic) {
+ kfree(shdrs);
+ return -ENOMEM;
+ }
+
+ retval = kernel_read(file, shdr->sh_offset,
+ (char *) params->dynamic, shdr->sh_size);
+
+ if (unlikely(retval != shdr->sh_size)) {
+ kfree(shdrs);
+ return retval < 0 ? retval : -ENOEXEC;
+ }
+ break;
+ }
+ return 0;
+}
+
+/*
+ * search for dynamic section tag value
+ */
+static elf_dyn *find_dynamic_tag(struct elf_dsbt_params *params,
+ dt_tag_t tag)
+{
+ elf_dyn *d = params->dynamic;
+
+ while (d->d_tag) {
+ if (d->d_tag == tag)
+ return d;
+ ++d;
+ }
+ return NULL;
+}
+
+#ifndef ELF_BASE_PLATFORM
+/*
+ * AT_BASE_PLATFORM indicates the "real" hardware/microarchitecture.
+ * If the arch defines ELF_BASE_PLATFORM (in asm/elf.h), the value
+ * will be copied to the user stack in the same manner as AT_PLATFORM.
+ */
+#define ELF_BASE_PLATFORM NULL
+#endif
+
+/*
+ * transfer the program arguments and environment from the holding pages onto
+ * the stack
+ */
+static int elf_dsbt_transfer_args_to_stack(struct linux_binprm *bprm,
+ unsigned long *_sp)
+{
+ unsigned long index, stop, sp;
+ char *src;
+ int ret = 0;
+
+ stop = bprm->p >> PAGE_SHIFT;
+ sp = *_sp;
+
+ for (index = MAX_ARG_PAGES - 1; index >= stop; index--) {
+ src = kmap(bprm->page[index]);
+ sp -= PAGE_SIZE;
+ if (copy_to_user((void *) sp, src, PAGE_SIZE) != 0)
+ ret = -EFAULT;
+ kunmap(bprm->page[index]);
+ if (ret < 0)
+ goto out;
+ }
+
+ *_sp = (*_sp - (MAX_ARG_PAGES * PAGE_SIZE - bprm->p)) & ~15;
+
+out:
+ return ret;
+}
+
+/*
+ * present useful information to the program by shovelling it onto the new
+ * process's stack
+ */
+static int create_elf_dsbt_tables(struct linux_binprm *bprm,
+ struct mm_struct *mm,
+ struct elf_dsbt_params *exec_params,
+ struct elf_dsbt_params *interp_params)
+{
+ const struct cred *cred = current_cred();
+ unsigned long sp, csp, nitems;
+ elf_caddr_t __user *argv, *envp;
+ size_t platform_len = 0, len;
+ char *k_platform, *k_base_platform;
+ char __user *u_platform, *u_base_platform, *p;
+ long hwcap;
+ int loop;
+ int nr; /* reset for each csp adjustment */
+
+ sp = mm->start_stack;
+
+ /* stack the program arguments and environment */
+ if (elf_dsbt_transfer_args_to_stack(bprm, &sp) < 0)
+ return -EFAULT;
+
+ hwcap = ELF_HWCAP;
+
+ /*
+ * If this architecture has a platform capability string, copy it
+ * to userspace. In some cases (Sparc), this info is impossible
+ * for userspace to get any other way, in others (i386) it is
+ * merely difficult.
+ */
+ k_platform = ELF_PLATFORM;
+ u_platform = NULL;
+
+ if (k_platform) {
+ platform_len = strlen(k_platform) + 1;
+ sp -= platform_len;
+ u_platform = (char __user *) sp;
+ if (__copy_to_user(u_platform, k_platform, platform_len) != 0)
+ return -EFAULT;
+ }
+
+ /*
+ * If this architecture has a "base" platform capability
+ * string, copy it to userspace.
+ */
+ k_base_platform = ELF_BASE_PLATFORM;
+ u_base_platform = NULL;
+
+ if (k_base_platform) {
+ platform_len = strlen(k_base_platform) + 1;
+ sp -= platform_len;
+ u_base_platform = (char __user *) sp;
+ if (__copy_to_user(u_base_platform, k_base_platform,
+ platform_len) != 0)
+ return -EFAULT;
+ }
+
+ sp &= ~7UL;
+
+ /* stack the load map(s) */
+ len = sizeof(struct elf32_dsbt_loadmap);
+ len += sizeof(struct elf32_dsbt_loadseg) * exec_params->loadmap->nsegs;
+ sp = (sp - len) & ~7UL;
+ exec_params->map_addr = sp;
+ kdebug("exec_params->map_addr[%x]", sp);
+
+ if (copy_to_user((void __user *) sp, exec_params->loadmap, len) != 0)
+ return -EFAULT;
+
+ current->mm->context.exec_dsbt_loadmap = (unsigned long) sp;
+
+ if (interp_params->loadmap) {
+ len = sizeof(struct elf32_dsbt_loadmap);
+ len += sizeof(struct elf32_dsbt_loadseg) *
+ interp_params->loadmap->nsegs;
+ sp = (sp - len) & ~7UL;
+ interp_params->map_addr = sp;
+ kdebug("interp_params->map_addr[%x]", sp);
+ if (copy_to_user((void __user *) sp, interp_params->loadmap,
+ len) != 0)
+ return -EFAULT;
+
+ current->mm->context.interp_dsbt_loadmap = (unsigned long) sp;
+ }
+
+ /* force 16 byte _final_ alignment here for generality */
+#define DLINFO_ITEMS 15
+
+ nitems = 1 + DLINFO_ITEMS + (k_platform ? 1 : 0) +
+ (k_base_platform ? 1 : 0) + AT_VECTOR_SIZE_ARCH;
+
+ if (bprm->interp_flags & BINPRM_FLAGS_EXECFD)
+ nitems++;
+
+ csp = sp;
+ sp -= nitems * 2 * sizeof(unsigned long);
+ sp -= (bprm->envc + 1) * sizeof(char *); /* envv[] */
+ sp -= (bprm->argc + 1) * sizeof(char *); /* argv[] */
+ sp -= 1 * sizeof(unsigned long); /* argc */
+
+ csp -= sp & 15UL;
+ sp -= sp & 15UL;
+
+ /* put the ELF interpreter info on the stack */
+#define NEW_AUX_ENT(id, val) \
+ do { \
+ struct { unsigned long _id, _val; } __user *ent; \
+ \
+ ent = (void __user *) csp; \
+ __put_user((id), &ent[nr]._id); \
+ __put_user((val), &ent[nr]._val); \
+ nr++; \
+ } while (0)
+
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_NULL, 0);
+ if (k_platform) {
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_PLATFORM,
+ (elf_addr_t) (unsigned long) u_platform);
+ }
+
+ if (k_base_platform) {
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_BASE_PLATFORM,
+ (elf_addr_t) (unsigned long) u_base_platform);
+ }
+
+ if (bprm->interp_flags & BINPRM_FLAGS_EXECFD) {
+ nr = 0;
+ csp -= 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_EXECFD, bprm->interp_data);
+ }
+
+ nr = 0;
+ csp -= DLINFO_ITEMS * 2 * sizeof(unsigned long);
+ NEW_AUX_ENT(AT_HWCAP, hwcap);
+ NEW_AUX_ENT(AT_PAGESZ, PAGE_SIZE);
+ NEW_AUX_ENT(AT_CLKTCK, CLOCKS_PER_SEC);
+ NEW_AUX_ENT(AT_PHDR, exec_params->ph_addr);
+ NEW_AUX_ENT(AT_PHENT, sizeof(struct elf_phdr));
+ NEW_AUX_ENT(AT_PHNUM, exec_params->hdr.e_phnum);
+ NEW_AUX_ENT(AT_BASE, interp_params->elfhdr_addr);
+ NEW_AUX_ENT(AT_FLAGS, 0);
+ NEW_AUX_ENT(AT_ENTRY, exec_params->entry_addr);
+ NEW_AUX_ENT(AT_UID, (elf_addr_t) cred->uid);
+ NEW_AUX_ENT(AT_EUID, (elf_addr_t) cred->euid);
+ NEW_AUX_ENT(AT_GID, (elf_addr_t) cred->gid);
+ NEW_AUX_ENT(AT_EGID, (elf_addr_t) cred->egid);
+ NEW_AUX_ENT(AT_SECURE, security_bprm_secureexec(bprm));
+ NEW_AUX_ENT(AT_EXECFN, bprm->exec);
+
+ kdebug("AUX entry start: %x]", csp);
+#ifdef ARCH_DLINFO
+ nr = 0;
+ csp -= AT_VECTOR_SIZE_ARCH * 2 * sizeof(unsigned long);
+
+ /* ARCH_DLINFO must come last so platform specific code can enforce
+ * special alignment requirements on the AUXV if necessary (eg. PPC).
+ */
+ ARCH_DLINFO;
+#endif
+#undef NEW_AUX_ENT
+
+ /* allocate room for argv[] and envv[] */
+ csp -= (bprm->envc + 1) * sizeof(elf_caddr_t);
+ envp = (elf_caddr_t __user *) csp;
+ csp -= (bprm->argc + 1) * sizeof(elf_caddr_t);
+ argv = (elf_caddr_t __user *) csp;
+
+ kdebug("argv[%x] envp[%x]\n", argv, envp);
+
+ /* stack argc */
+ csp -= sizeof(unsigned long);
+ __put_user(bprm->argc, (unsigned long __user *) csp);
+
+ BUG_ON(csp != sp);
+
+ /* fill in the argv[] array */
+ current->mm->arg_start = current->mm->start_stack -
+ (MAX_ARG_PAGES * PAGE_SIZE - bprm->p);
+
+ p = (char __user *) current->mm->arg_start;
+ for (loop = bprm->argc; loop > 0; loop--) {
+ __put_user((elf_caddr_t) p, argv++);
+ len = strnlen_user(p, MAX_ARG_STRLEN);
+ if (!len || len > MAX_ARG_STRLEN)
+ return -EINVAL;
+ p += len;
+ }
+ __put_user(NULL, argv);
+ current->mm->arg_end = (unsigned long) p;
+
+ /* fill in the envv[] array */
+ current->mm->env_start = (unsigned long) p;
+ for (loop = bprm->envc; loop > 0; loop--) {
+ __put_user((elf_caddr_t)(unsigned long) p, envp++);
+ len = strnlen_user(p, MAX_ARG_STRLEN);
+ if (!len || len > MAX_ARG_STRLEN)
+ return -EINVAL;
+ p += len;
+ }
+ __put_user(NULL, envp);
+ current->mm->env_end = (unsigned long) p;
+
+ mm->start_stack = (unsigned long) sp;
+ return 0;
+}
+
+/*
+ * map a single segment
+ */
+static unsigned long elf_dsbt_map(struct file *filep, unsigned long addr,
+ struct elf32_dsbt_seg *seg, int prot, int type)
+{
+ unsigned long map_addr;
+ unsigned long size = seg->p_memsz + ELF_PAGEOFFSET(seg->p_vaddr);
+ unsigned long off = seg->p_offset - ELF_PAGEOFFSET(seg->p_vaddr);
+ addr = ELF_PAGESTART(addr);
+ size = ELF_PAGEALIGN(size);
+
+ /* mmap() will return -EINVAL if given a zero size, but a
+ * segment with zero filesize is perfectly valid */
+ if (!size)
+ return addr;
+
+ down_write(&current->mm->mmap_sem);
+ map_addr = do_mmap(filep, addr, size, prot, type, off);
+ up_write(&current->mm->mmap_sem);
+ return map_addr;
+}
+
+/*
+ * load the appropriate binary image (executable or interpreter) into memory
+ * - we assume no MMU is available
+ * - we assume that there is one LOADable segment with execute flags
+ * - we assume that there is one LOADable segment without execute flags
+ */
+static int elf_dsbt_map_file(struct elf_dsbt_params *params,
+ struct file *file,
+ struct mm_struct *mm,
+ const char *what,
+ const char *interp_name)
+{
+ struct elf32_phdr *phdr, *code_phdr = NULL;
+ struct elf32_phdr *data_phdr = NULL;
+ struct elf32_phdr *dyn_phdr = NULL;
+ struct elf32_dsbt_loadmap *loadmap;
+ struct elf32_dsbt_loadseg *seg;
+ elf_dyn *dyn;
+ unsigned long mapped_addr, bss_len;
+ int loop, ret, flags, ndseg, prot;
+
+ phdr = params->phdrs;
+ ndseg = 0;
+ for (loop = 0; loop < params->hdr.e_phnum; loop++, phdr++) {
+ if (phdr->p_type == PT_DYNAMIC)
+ dyn_phdr = phdr;
+
+ if (phdr->p_type != PT_LOAD)
+ continue;
+
+ kdebug("elf_dsbt_map_file: [LOAD] va=%lx of=%lx "
+ "fs=%lx ms=%lx flags=%lx",
+ (unsigned long) phdr->p_vaddr,
+ (unsigned long) phdr->p_offset,
+ (unsigned long) phdr->p_filesz,
+ (unsigned long) phdr->p_memsz,
+ (unsigned long) phdr->p_flags);
+
+ if (ELF_PAGEOFFSET(phdr->p_offset) != ELF_PAGEOFFSET(phdr->p_vaddr)) {
+ kdebug("Bad ELF file!");
+ return -EINVAL;
+ }
+
+ /*
+ * There should be only one executable segment and
+ * one RW segment.
+ */
+ if (phdr->p_flags & PF_X) {
+ if (code_phdr) {
+ kdebug("more than one executable segment!");
+ return -EINVAL;
+ }
+ code_phdr = phdr;
+ } else {
+ if (data_phdr) {
+ kdebug("more than one RW segment!");
+ return -EINVAL;
+ }
+ data_phdr = phdr;
+ }
+ }
+ if (!code_phdr) {
+ kdebug("no executable segment!");
+ return -EINVAL;
+ }
+ if (!data_phdr) {
+ kdebug("no RW segment!");
+ return -EINVAL;
+ }
+
+ params->code_seg.p_vaddr = code_phdr->p_vaddr;
+ params->code_seg.p_offset = code_phdr->p_offset;
+ params->code_seg.p_memsz = code_phdr->p_memsz;
+ params->code_seg.p_filesz = code_phdr->p_filesz;
+
+ params->data_seg.p_vaddr = data_phdr->p_vaddr;
+ params->data_seg.p_offset = data_phdr->p_offset;
+ params->data_seg.p_memsz = data_phdr->p_memsz;
+ params->data_seg.p_filesz = data_phdr->p_filesz;
+
+ /* map code segment */
+ flags = MAP_PRIVATE | MAP_DENYWRITE;
+ if (params->flags & ELF_DSBT_FLAG_EXECUTABLE)
+ flags |= MAP_EXECUTABLE;
+
+ prot = PROT_READ | PROT_EXEC;
+
+ mapped_addr = elf_dsbt_map(file, params->code_seg.p_vaddr,
+ &params->code_seg, prot, flags);
+ if (BAD_ADDR(mapped_addr))
+ return (int) mapped_addr;
+
+ params->code_seg.addr = mapped_addr +
+ ELF_PAGEOFFSET(params->code_seg.p_vaddr);
+
+ kdebug("mapped code seg from %08x to %08x",
+ params->code_seg.p_vaddr, params->code_seg.addr);
+
+ /* map data segment */
+ mapped_addr = elf_dsbt_map(file, params->data_seg.p_vaddr,
+ &params->data_seg,
+ PROT_READ | PROT_WRITE, MAP_PRIVATE);
+ if (BAD_ADDR(mapped_addr)) {
+ do_munmap(current->mm, mapped_addr,
+ params->data_seg.p_memsz);
+ return (int) mapped_addr;
+ }
+ params->data_seg.addr = mapped_addr +
+ ELF_PAGEOFFSET(params->data_seg.p_vaddr);
+
+ kdebug("mapped data seg from %08x to %08x",
+ params->data_seg.p_vaddr, params->data_seg.addr);
+
+ /* clear any bss area */
+ bss_len = params->data_seg.p_memsz - params->data_seg.p_filesz;
+ if (bss_len) {
+ unsigned long bss_start;
+
+ bss_start = params->data_seg.addr + params->data_seg.p_filesz;
+
+ kdebug("clearing %d bytes of bss at %08x", bss_len, bss_start);
+ ret = clear_user((void *)bss_start, bss_len);
+ if (ret)
+ return ret;
+ }
+
+ /* fetch dsbt info from dynamic section */
+ dyn = find_dynamic_tag(params, DT_ARCH_DSBT_BASE);
+ if (!dyn) {
+ kdebug("DSBT BASE not found");
+ return -EINVAL;
+ }
+ /* relocate it */
+ params->dsbt_base = (dyn->d_un.d_ptr - params->data_seg.p_vaddr) +
+ params->data_seg.addr;
+
+ dyn = find_dynamic_tag(params, DT_ARCH_DSBT_SIZE);
+ if (!dyn) {
+ kdebug("DSBT SIZE not found");
+ return -EINVAL;
+ }
+ params->dsbt_size = dyn->d_un.d_ptr;
+
+ dyn = find_dynamic_tag(params, DT_ARCH_DSBT_INDEX);
+ if (!dyn) {
+ kdebug("DSBT INDEX not found");
+ return -EINVAL;
+ }
+ params->dsbt_index = dyn->d_un.d_ptr;
+
+ /* determine where the elf header has wound up if mapped */
+ if (params->code_seg.p_offset == 0)
+ params->elfhdr_addr = params->code_seg.addr;
+ else if (params->data_seg.p_offset == 0)
+ params->elfhdr_addr = params->data_seg.addr;
+ else {
+ /* elf header has not been mapped */
+ kdebug("elf header not mapped!");
+ return -EINVAL;
+ }
+
+ /* determine where the program header table has wound up if mapped */
+ if (params->hdr.e_phoff >= params->code_seg.p_offset &&
+ params->hdr.e_phoff < params->code_seg.p_offset + params->code_seg.p_memsz)
+ params->ph_addr = params->code_seg.addr +
+ (params->hdr.e_phoff - params->code_seg.p_offset);
+ else if (params->hdr.e_phoff >= params->data_seg.p_offset &&
+ params->hdr.e_phoff < params->data_seg.p_offset + params->data_seg.p_memsz)
+ params->ph_addr = params->data_seg.addr +
+ (params->hdr.e_phoff - params->data_seg.p_offset);
+ else {
+ /* program header has not been mapped */
+ kdebug("program header not mapped!");
+ return -EINVAL;
+ }
+
+ /* determine where the dynamic section has wound up if there is one */
+ if (dyn_phdr) {
+ if (dyn_phdr->p_offset >= params->code_seg.p_offset &&
+ dyn_phdr->p_offset < params->code_seg.p_offset + params->code_seg.p_memsz)
+ params->dynamic_addr = params->code_seg.addr +
+ (dyn_phdr->p_offset - params->code_seg.p_offset);
+ else if (dyn_phdr->p_offset >= params->data_seg.p_offset &&
+ dyn_phdr->p_offset < params->data_seg.p_offset + params->data_seg.p_memsz)
+ params->dynamic_addr = params->data_seg.addr +
+ (dyn_phdr->p_offset - params->data_seg.p_offset);
+ else {
+ /* dynamic section has not been mapped */
+ kdebug("dynamic section not mapped!");
+ return -EINVAL;
+ }
+ }
+
+ loadmap = kmalloc(sizeof(*loadmap) +
+ (2 * sizeof(struct elf32_dsbt_loadseg)), GFP_KERNEL);
+ if (!loadmap)
+ return -ENOMEM;
+
+ params->loadmap = loadmap;
+
+ loadmap->version = ELF_DSBT_LOADMAP_VERSION;
+ loadmap->dsbt_table = (unsigned *)params->dsbt_base;
+ loadmap->dsbt_size = params->dsbt_size;
+ loadmap->dsbt_index = params->dsbt_index;
+ loadmap->nsegs = 2;
+
+ seg = loadmap->segs;
+
+ seg->addr = params->code_seg.addr;
+ seg->p_vaddr = params->code_seg.p_vaddr;
+ seg->p_memsz = params->code_seg.p_memsz;
+ ++seg;
+ seg->addr = params->data_seg.addr;
+ seg->p_vaddr = params->data_seg.p_vaddr;
+ seg->p_memsz = params->data_seg.p_memsz;
+ ++seg;
+
+ /* map the entry point */
+ if (params->hdr.e_entry)
+ params->entry_addr = params->code_seg.addr +
+ (params->hdr.e_entry - params->code_seg.p_vaddr);
+
+ if (mm) {
+ if (!mm->start_code) {
+ mm->start_code = params->code_seg.addr;
+ mm->end_code = params->code_seg.addr +
+ params->code_seg.p_memsz;
+ }
+
+ if (!mm->start_data) {
+ mm->start_data = params->data_seg.addr;
+ mm->end_data = params->data_seg.addr +
+ params->data_seg.p_memsz;
+ }
+ }
+
+ kdebug("Mapped Object [%s]:", what);
+ kdebug("- elfhdr : %lx", params->elfhdr_addr);
+ kdebug("- PHDR[] : %lx", params->ph_addr);
+ kdebug("- entry : %lx", params->entry_addr);
+ kdebug("- DYNAMIC[]: %lx", params->dynamic_addr);
+ kdebug("- CODE : %lx", params->code_seg.addr);
+ kdebug("- DATA : %lx", params->data_seg.addr);
+ kdebug("- DSBT TBL : %lx", loadmap->dsbt_table);
+ kdebug("- DSBT SZ : %d", loadmap->dsbt_size);
+ kdebug("- DSBT IDX : %d", loadmap->dsbt_index);
+
+ return 0;
+}
+
+/*
+ * load a DSBT binary into various bits of memory
+ */
+static int load_elf_dsbt_binary(struct linux_binprm *bprm,
+ struct pt_regs *regs)
+{
+ struct elf_dsbt_params exec_params, interp_params;
+ struct elf_phdr *phdr;
+ unsigned long stack_size, entryaddr;
+#ifdef ELF_DSBT_PLAT_INIT
+ unsigned long dynaddr, dsbt_table;
+#endif
+ unsigned long stack_prot;
+ struct file *interpreter = NULL; /* to shut gcc up */
+ char *interpreter_name = NULL;
+ int executable_stack;
+ int retval, i;
+
+ kdebug("____ LOAD pid[%d] ____", current->pid);
+
+ memset(&exec_params, 0, sizeof(exec_params));
+ memset(&interp_params, 0, sizeof(interp_params));
+
+ exec_params.hdr = *(struct elfhdr *) bprm->buf;
+ exec_params.flags = ELF_DSBT_FLAG_EXECUTABLE | ELF_DSBT_FLAG_PRESENT;
+
+ /* check that this is a binary we know how to deal with */
+ retval = -ENOEXEC;
+ if (!is_elf_dsbt(&exec_params.hdr, bprm->file)) {
+ kdebug("not DSBT binary!");
+ goto error;
+ }
+
+ /* read the program header table */
+ retval = elf_dsbt_fetch_phdrs(&exec_params, bprm->file);
+ if (retval < 0) {
+ kdebug("can't get phdrs!");
+ goto error;
+ }
+
+ /* read the dynamic section */
+ retval = elf_dsbt_fetch_dynamic(&exec_params, bprm->file);
+ if (retval < 0) {
+ kdebug("can't get dynamic section!");
+ goto error;
+ }
+
+ /* scan for a program header that specifies an interpreter */
+ phdr = exec_params.phdrs;
+
+ for (i = 0; i < exec_params.hdr.e_phnum; i++, phdr++) {
+ switch (phdr->p_type) {
+ case PT_INTERP:
+ kdebug("found PT_INTERP");
+ retval = -ENOMEM;
+ if (phdr->p_filesz > PATH_MAX)
+ goto error;
+ retval = -ENOENT;
+ if (phdr->p_filesz < 2)
+ goto error;
+
+ /* read the name of the interpreter into memory */
+ interpreter_name = kmalloc(phdr->p_filesz, GFP_KERNEL);
+ if (!interpreter_name)
+ goto error;
+
+ retval = kernel_read(bprm->file,
+ phdr->p_offset,
+ interpreter_name,
+ phdr->p_filesz);
+ if (unlikely(retval != phdr->p_filesz)) {
+ if (retval >= 0)
+ retval = -ENOEXEC;
+ goto error;
+ }
+
+ retval = -ENOENT;
+ if (interpreter_name[phdr->p_filesz - 1] != '\0')
+ goto error;
+
+ kdebug("Using ELF interpreter %s", interpreter_name);
+
+ /* replace the program with the interpreter */
+ interpreter = open_exec(interpreter_name);
+ retval = PTR_ERR(interpreter);
+ if (IS_ERR(interpreter)) {
+ interpreter = NULL;
+ goto error;
+ }
+
+ /*
+ * If the binary is not readable then enforce
+ * mm->dumpable = 0 regardless of the interpreter's
+ * permissions.
+ */
+ if (file_permission(interpreter, MAY_READ) < 0)
+ bprm->interp_flags |= BINPRM_FLAGS_ENFORCE_NONDUMP;
+
+ retval = kernel_read(interpreter, 0, bprm->buf,
+ BINPRM_BUF_SIZE);
+ if (unlikely(retval != BINPRM_BUF_SIZE)) {
+ if (retval >= 0)
+ retval = -ENOEXEC;
+ goto error;
+ }
+
+ interp_params.hdr = *((struct elfhdr *) bprm->buf);
+ break;
+
+ case PT_LOAD:
+ kdebug("found PT_LOAD");
+ break;
+ }
+
+ }
+ /* perform insanity checks on the interpreter */
+ if (interpreter_name) {
+ retval = -ELIBBAD;
+ if (!is_elf_dsbt(&interp_params.hdr, interpreter))
+ goto error;
+
+ interp_params.flags = ELF_DSBT_FLAG_PRESENT;
+
+ /* read the interpreter's program header table */
+ retval = elf_dsbt_fetch_phdrs(&interp_params, interpreter);
+ if (retval < 0)
+ goto error;
+
+ /* read the interpreter's dynamic section */
+ retval = elf_dsbt_fetch_dynamic(&interp_params, interpreter);
+ if (retval < 0) {
+ kdebug("can't get dynamic section!");
+ goto error;
+ }
+ }
+
+ executable_stack = EXSTACK_DEFAULT;
+
+ stack_size = interp_params.stack_size;
+
+ retval = -ENOEXEC;
+ if (stack_size == 0) {
+#if 0
+ kdebug("zero stack size");
+ goto error;
+#else
+ stack_size = 0x8000;
+#endif
+ }
+
+ /* flush all traces of the currently running executable */
+ retval = flush_old_exec(bprm);
+ if (retval) {
+ kdebug("flush_old_exec returned: %d", retval);
+ goto error;
+ }
+
+ /* there's now no turning back... the old userspace image is dead,
+ * defunct, deceased, etc. after this point we have to exit via
+ * error_kill */
+ set_personality(PER_LINUX);
+ if (elf_read_implies_exec(&exec_params.hdr, executable_stack))
+ current->personality |= READ_IMPLIES_EXEC;
+
+ setup_new_exec(bprm);
+
+ set_binfmt(&elf_dsbt_format);
+
+ current->mm->start_code = 0;
+ current->mm->end_code = 0;
+ current->mm->start_stack = 0;
+ current->mm->start_data = 0;
+ current->mm->end_data = 0;
+
+ current->flags &= ~PF_FORKNOEXEC;
+
+ /* load the executable and interpreter into memory */
+ retval = elf_dsbt_map_file(&exec_params, bprm->file, current->mm,
+ "executable", interpreter_name);
+ if (retval < 0) {
+ kdebug("elf_dsbt_map_file: returned %d", retval);
+ goto error_kill;
+ }
+
+ if (interpreter_name) {
+ retval = elf_dsbt_map_file(&interp_params, interpreter,
+ current->mm, "interpreter", NULL);
+ if (retval < 0) {
+ printk(KERN_ERR "Unable to load interpreter");
+ goto error_kill;
+ }
+
+ allow_write_access(interpreter);
+ fput(interpreter);
+ interpreter = NULL;
+ }
+
+ /* create a stack and brk area big enough for everyone
+ * - the brk heap starts at the bottom and works up
+ * - the stack starts at the top and works down
+ */
+ stack_size = (stack_size + PAGE_SIZE - 1) & PAGE_MASK;
+ if (stack_size < PAGE_SIZE * 2)
+ stack_size = PAGE_SIZE * 2;
+
+ stack_prot = PROT_READ | PROT_WRITE;
+ if (executable_stack == EXSTACK_ENABLE_X ||
+ (executable_stack == EXSTACK_DEFAULT && VM_STACK_FLAGS & VM_EXEC))
+ stack_prot |= PROT_EXEC;
+
+ down_write(&current->mm->mmap_sem);
+ current->mm->start_brk = do_mmap(NULL, 0, stack_size, stack_prot,
+ MAP_PRIVATE | MAP_ANONYMOUS |
+ MAP_UNINITIALIZED | MAP_GROWSDOWN,
+ 0);
+
+ if (IS_ERR_VALUE(current->mm->start_brk)) {
+ up_write(&current->mm->mmap_sem);
+ retval = current->mm->start_brk;
+ current->mm->start_brk = 0;
+ kdebug("do_mmap failed");
+ goto error_kill;
+ }
+
+ up_write(&current->mm->mmap_sem);
+
+ current->mm->brk = current->mm->start_brk;
+ current->mm->context.end_brk = current->mm->start_brk;
+ current->mm->context.end_brk +=
+ (stack_size > PAGE_SIZE) ? (stack_size - PAGE_SIZE) : 0;
+ current->mm->start_stack = current->mm->start_brk + stack_size;
+
+ install_exec_creds(bprm);
+ current->flags &= ~PF_FORKNOEXEC;
+ if (create_elf_dsbt_tables(bprm, current->mm,
+ &exec_params, &interp_params) < 0) {
+ kdebug("create_eld_dsbt_tables failed");
+ goto error_kill;
+ }
+
+ kdebug("- start_code %lx", current->mm->start_code);
+ kdebug("- end_code %lx", current->mm->end_code);
+ kdebug("- start_data %lx", current->mm->start_data);
+ kdebug("- end_data %lx", current->mm->end_data);
+ kdebug("- start_brk %lx", current->mm->start_brk);
+ kdebug("- brk %lx", current->mm->brk);
+ kdebug("- start_stack %lx", current->mm->start_stack);
+
+#ifdef ELF_DSBT_PLAT_INIT
+ /*
+ * The ABI may specify that certain registers be set up in special
+ * ways. This macro performs whatever initialization to the regs
+ * structure is required.
+ */
+ if (interp_params.dynamic_addr) {
+ dynaddr = interp_params.dynamic_addr;
+ dsbt_table = (unsigned long)interp_params.loadmap->dsbt_table;
+ } else {
+ dynaddr = exec_params.dynamic_addr;
+ dsbt_table = (unsigned long)exec_params.loadmap->dsbt_table;
+ }
+
+ kdebug("exec_params.map_addr[%x]", exec_params.map_addr);
+ kdebug("interp_params.map_addr[%x]", interp_params.map_addr);
+ ELF_DSBT_PLAT_INIT(regs,
+ exec_params.map_addr,
+ interp_params.map_addr,
+ dynaddr, dsbt_table);
+#endif
+
+ /* everything is now ready... get the userspace context ready to roll */
+ if (interp_params.entry_addr)
+ entryaddr = interp_params.entry_addr;
+ else
+ entryaddr = exec_params.entry_addr;
+
+ start_thread(regs, entryaddr, current->mm->start_stack);
+
+ retval = 0;
+error:
+ kdebug("load returning: %d", retval);
+ if (interpreter) {
+ allow_write_access(interpreter);
+ fput(interpreter);
+ }
+ kfree(interpreter_name);
+ kfree(exec_params.phdrs);
+ kfree(interp_params.phdrs);
+ kfree(exec_params.dynamic);
+ kfree(interp_params.dynamic);
+ kfree(exec_params.loadmap);
+ kfree(interp_params.loadmap);
+ return retval;
+
+ /* unrecoverable error - kill the process */
+error_kill:
+ send_sig(SIGSEGV, current, 0);
+ goto error;
+
+}
+
+static int __init init_elf_dsbt_binfmt(void)
+{
+ return register_binfmt(&elf_dsbt_format);
+}
+
+static void __exit exit_elf_dsbt_binfmt(void)
+{
+ unregister_binfmt(&elf_dsbt_format);
+}
+
+core_initcall(init_elf_dsbt_binfmt);
+module_exit(exit_elf_dsbt_binfmt);
+MODULE_LICENSE("GPL");
diff --git a/include/linux/elf-dsbt.h b/include/linux/elf-dsbt.h
new file mode 100644
index 0000000..dadc400
--- /dev/null
+++ b/include/linux/elf-dsbt.h
@@ -0,0 +1,88 @@
+/* elf-dsbt.h: DSBT ELF load map
+ *
+ * Copyright (C) 2010, 2011 Texas Instruments Incorporated
+ * Written by Mark Salter <[email protected]>
+ * Based on elf-fdpic.h
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ */
+
+#ifndef _LINUX_ELF_DSBT_H
+#define _LINUX_ELF_DSBT_H
+
+#include <linux/elf.h>
+
+#if ELF_CLASS == ELFCLASS32
+#define elf_dyn Elf32_Dyn
+#else
+#define elf_dyn Elf64_Dyn
+#endif
+
+#define ELF_DSBT_LOADMAP_VERSION 0x0000
+
+/* This data structure represents a PT_LOAD segment. */
+struct elf32_dsbt_loadseg {
+ /* Core address to which the segment is mapped. */
+ Elf32_Addr addr;
+ /* VMA recorded in the program header. */
+ Elf32_Addr p_vaddr;
+ /* Size of this segment in memory. */
+ Elf32_Word p_memsz;
+};
+
+struct elf32_dsbt_loadmap {
+ /* Protocol version number, must be zero. */
+ Elf32_Word version;
+
+ /* Pointer to DSBT */
+ unsigned *dsbt_table;
+ unsigned dsbt_size;
+ unsigned dsbt_index;
+
+ /* number of segments */
+ Elf32_Word nsegs;
+
+ /* The actual memory map. */
+ struct elf32_dsbt_loadseg segs[0];
+};
+
+/* internal segment mappings for ELF DSBT loader */
+struct elf32_dsbt_seg {
+ Elf32_Addr addr; /* core address to which mapped */
+ Elf32_Addr p_vaddr; /* VMA recorded in file */
+ Elf32_Off p_offset; /* file offset */
+ Elf32_Word p_filesz; /* initialized data in file */
+ Elf32_Word p_memsz; /* allocation size recorded in file */
+};
+
+/*
+ * binfmt binary parameters structure
+ */
+struct elf_dsbt_params {
+ struct elfhdr hdr; /* ref copy of ELF header */
+ struct elf_phdr *phdrs; /* ref copy of PT_PHDR table */
+ elf_dyn *dynamic; /* ref copy of .dynamic section */
+ struct elf32_dsbt_seg code_seg; /* mapping for code segment */
+ struct elf32_dsbt_seg data_seg; /* mapping for data segment */
+ struct elf32_dsbt_seg *extra_segs; /* mapping for extra segments */
+ struct elf32_dsbt_loadmap *loadmap; /* loadmap to be passed to userspace */
+ int num_new;
+ unsigned long elfhdr_addr; /* mapped ELF header user address */
+ unsigned long ph_addr; /* mapped PT_PHDR user address */
+ unsigned long map_addr; /* mapped loadmap user address */
+ unsigned long entry_addr; /* mapped entry user address */
+ unsigned long stack_size; /* stack size requested (PT_GNU_STACK) */
+ unsigned long dynamic_addr; /* mapped PT_DYNAMIC user address */
+ unsigned long flags;
+ unsigned long dsbt_base;
+ unsigned int dsbt_size;
+ unsigned int dsbt_index;
+
+#define ELF_DSBT_FLAG_PRESENT 0x00000001 /* T if this object is present */
+#define ELF_DSBT_FLAG_EXECUTABLE 0x00000002 /* T if this object is the executable */
+};
+
+#endif /* _LINUX_ELF_DSBT_H */
--
1.6.2.5

2011-05-11 21:06:46

by Mark Salter

[permalink] [raw]
Subject: [PATCH 16/16] C6X: add support for DSBT binary format

This patch adds the C6X-specifc bits to use the DSBT binary format.

Signed-off-by: Mark Salter <[email protected]>
---
arch/c6x/configs/ti_dsk6455_defconfig | 1 +
arch/c6x/configs/ti_evmc6457_defconfig | 1 +
arch/c6x/configs/ti_evmc6472_defconfig | 1 +
arch/c6x/configs/ti_evmc6474_defconfig | 1 +
arch/c6x/configs/ti_evmc6474_lite_defconfig | 1 +
arch/c6x/include/asm/elf.h | 14 ++++++++++++++
arch/c6x/include/asm/mmu.h | 4 ++++
arch/c6x/include/asm/ptrace.h | 12 ++++++++++++
arch/c6x/kernel/ptrace.c | 25 ++++++++++++++++++++++++-
9 files changed, 59 insertions(+), 1 deletions(-)

diff --git a/arch/c6x/configs/ti_dsk6455_defconfig b/arch/c6x/configs/ti_dsk6455_defconfig
index 3487af4..8112a70 100644
--- a/arch/c6x/configs/ti_dsk6455_defconfig
+++ b/arch/c6x/configs/ti_dsk6455_defconfig
@@ -229,6 +229,7 @@ CONFIG_HIGH_RES_TIMERS=y
#
# Executable file formats
#
+CONFIG_BINFMT_ELF_DSBT=y
# CONFIG_BINFMT_FLAT is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
diff --git a/arch/c6x/configs/ti_evmc6457_defconfig b/arch/c6x/configs/ti_evmc6457_defconfig
index e18b095..841f15a 100644
--- a/arch/c6x/configs/ti_evmc6457_defconfig
+++ b/arch/c6x/configs/ti_evmc6457_defconfig
@@ -229,6 +229,7 @@ CONFIG_HIGH_RES_TIMERS=y
#
# Executable file formats
#
+CONFIG_BINFMT_ELF_DSBT=y
# CONFIG_BINFMT_FLAT is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
diff --git a/arch/c6x/configs/ti_evmc6472_defconfig b/arch/c6x/configs/ti_evmc6472_defconfig
index 14ae81b..b18e9ee 100644
--- a/arch/c6x/configs/ti_evmc6472_defconfig
+++ b/arch/c6x/configs/ti_evmc6472_defconfig
@@ -231,6 +231,7 @@ CONFIG_HIGH_RES_TIMERS=y
#
# Executable file formats
#
+CONFIG_BINFMT_ELF_DSBT=y
# CONFIG_BINFMT_FLAT is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
diff --git a/arch/c6x/configs/ti_evmc6474_defconfig b/arch/c6x/configs/ti_evmc6474_defconfig
index 472ad6b..12f1808 100644
--- a/arch/c6x/configs/ti_evmc6474_defconfig
+++ b/arch/c6x/configs/ti_evmc6474_defconfig
@@ -229,6 +229,7 @@ CONFIG_HIGH_RES_TIMERS=y
#
# Executable file formats
#
+CONFIG_BINFMT_ELF_DSBT=y
# CONFIG_BINFMT_FLAT is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
diff --git a/arch/c6x/configs/ti_evmc6474_lite_defconfig b/arch/c6x/configs/ti_evmc6474_lite_defconfig
index e25e8ac..044cf47 100644
--- a/arch/c6x/configs/ti_evmc6474_lite_defconfig
+++ b/arch/c6x/configs/ti_evmc6474_lite_defconfig
@@ -229,6 +229,7 @@ CONFIG_HIGH_RES_TIMERS=y
#
# Executable file formats
#
+CONFIG_BINFMT_ELF_DSBT=y
# CONFIG_BINFMT_FLAT is not set
# CONFIG_HAVE_AOUT is not set
# CONFIG_BINFMT_MISC is not set
diff --git a/arch/c6x/include/asm/elf.h b/arch/c6x/include/asm/elf.h
index 272c3ae..d57bb17 100644
--- a/arch/c6x/include/asm/elf.h
+++ b/arch/c6x/include/asm/elf.h
@@ -32,6 +32,7 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
*/
#define elf_check_arch(x) ((x)->e_machine == EM_TI_C6000)

+#define elf_check_dsbt(x) (1)
#define elf_check_const_displacement(x) (1)

/*
@@ -67,6 +68,14 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];

#define ELF_PLATFORM (NULL)

+#define ELF_DSBT_PLAT_INIT(_regs, _exec_map, _interp_map, _dynamic_addr, _dsbt_table) \
+do { \
+ _regs->b4 = (_exec_map); \
+ _regs->a6 = (_interp_map); \
+ _regs->b6 = (_dynamic_addr); \
+ _regs->dp = (_dsbt_table); \
+} while (0)
+
#define SET_PERSONALITY(ex) set_personality(PER_LINUX)

/* C6X specific section types */
@@ -112,4 +121,9 @@ typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
#define R_C6000_FPHEAD 254
#define R_C6000_NOCMP 255

+/* for binfmt_elf_dsbt */
+#define DT_ARCH_DSBT_BASE DT_C6000_DSBT_BASE
+#define DT_ARCH_DSBT_SIZE DT_C6000_DSBT_SIZE
+#define DT_ARCH_DSBT_INDEX DT_C6000_DSBT_INDEX
+
#endif /*_ASM_C6X_ELF_H */
diff --git a/arch/c6x/include/asm/mmu.h b/arch/c6x/include/asm/mmu.h
index 8d376e9..1d9e9c1 100644
--- a/arch/c6x/include/asm/mmu.h
+++ b/arch/c6x/include/asm/mmu.h
@@ -15,6 +15,10 @@

typedef struct {
unsigned long end_brk;
+#ifdef CONFIG_BINFMT_ELF_DSBT
+ unsigned long exec_dsbt_loadmap;
+ unsigned long interp_dsbt_loadmap;
+#endif
} mm_context_t;

#endif /* _ASM_C6X_MMU_H */
diff --git a/arch/c6x/include/asm/ptrace.h b/arch/c6x/include/asm/ptrace.h
index 7e94de8..437df6f 100644
--- a/arch/c6x/include/asm/ptrace.h
+++ b/arch/c6x/include/asm/ptrace.h
@@ -162,11 +162,23 @@ struct pt_regs {
REG_PAIR(sp, dp);
};

+/*
+ * These are 'magic' values for PTRACE_PEEKUSR that return info about where a
+ * process is located in memory.
+ */
+#define PT_TEXT_ADDR 0x10000
+#define PT_DATA_ADDR 0x10004
+#define PT_TEXT_END_ADDR 0x10008
+
#define PTRACE_GETREGS 12
#define PTRACE_SETREGS 13
#define PTRACE_GETFPREGS 14
#define PTRACE_SETFPREGS 15

+#define PTRACE_GETDSBT 31 /* get the ELF DSBT loadmap address */
+#define PTRACE_GETDSBT_EXEC 0 /* [addr] request the executable loadmap */
+#define PTRACE_GETDSBT_INTERP 1 /* [addr] request the interpreter loadmap */
+
#ifdef __KERNEL__

#define DEFAULT_CSR 0x0001 /* interrupt enable by default */
diff --git a/arch/c6x/kernel/ptrace.c b/arch/c6x/kernel/ptrace.c
index fd38463..aa853e4 100644
--- a/arch/c6x/kernel/ptrace.c
+++ b/arch/c6x/kernel/ptrace.c
@@ -167,7 +167,13 @@ static int ptrace_read_user(struct task_struct *tsk, unsigned long off,


tmp = 0;
- if (off < PT_REG_SIZE)
+ if (index == PT_TEXT_ADDR)
+ tmp = tsk->mm->start_code;
+ else if (index == PT_DATA_ADDR)
+ tmp = tsk->mm->start_data;
+ else if (index == PT_TEXT_END_ADDR)
+ tmp = tsk->mm->end_code;
+ else if (off < PT_REG_SIZE)
tmp = get_reg(tsk, index);
else
return -EIO;
@@ -250,6 +256,23 @@ long arch_ptrace(struct task_struct *child, long request,
}
break;

+ case PTRACE_GETDSBT: {
+ tmp = 0;
+ switch (addr) {
+ case PTRACE_GETDSBT_EXEC:
+ tmp = child->mm->context.exec_dsbt_loadmap;
+ break;
+ case PTRACE_GETDSBT_INTERP:
+ tmp = child->mm->context.interp_dsbt_loadmap;
+ break;
+ default:
+ break;
+ }
+
+ ret = put_user(tmp, (unsigned long __user *)data);
+ break;
+ }
+
default:
ret = ptrace_request(child, request, addr, data);
break;
--
1.6.2.5

2011-05-11 21:34:47

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Wed, 11 May 2011 16:13:47 -0400 Mark Salter wrote:

> The project wiki for linux-c6x is at:
>
> http://www.linux-c6x.org
>
> and the GIT tree holding the attached patches is at:
>
> [email protected]:/git/projects/linux-c6x-upstreaming.git
>
> TIA for any feedback and/or guidance on this port.

Hi,

Please run the patches thru checkpatch.pl. You don't have to fix everything
that it whines about, just use good judgment.

---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

2011-05-12 00:49:06

by Joe Perches

[permalink] [raw]
Subject: Re: [PATCH 03/16] add driver for C64x+ ethernet driver

On Wed, 2011-05-11 at 16:13 -0400, Mark Salter wrote:
> From: Aurelien Jacquiot <[email protected]>
>
> This patch adds a network driver to support the ethernet interface found on
> several Texas Instruments C64X+ based System on Chips. In particular, this
> driver has been tested on the TMS320C6455, TMS320C6457, TMS320C6472, and
> TMS320C6474 parts.

I'd rather you put this in a new ti_c6x subdirectory in drivers/net/
Please CC network drivers to [email protected] (added)

And some comments below.

> Signed-off-by: Aurelien Jacquiot <[email protected]>
> Signed-off-by: Mark Salter <[email protected]>
> ---
> drivers/net/Kconfig | 8 +
> drivers/net/Makefile | 2 +
> drivers/net/c6x_gemac.c | 1582 +++++++++++++++++++++++++++++++++++++++++++++++
> drivers/net/c6x_gmdio.c | 514 +++++++++++++++
> 4 files changed, 2106 insertions(+), 0 deletions(-)
> create mode 100644 drivers/net/c6x_gemac.c
> create mode 100644 drivers/net/c6x_gmdio.c
>
> diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
> index dc280bc..5eb46a1 100644
> --- a/drivers/net/Kconfig
> +++ b/drivers/net/Kconfig
> @@ -2910,6 +2910,14 @@ config BNA
>
> <http://support.brocade.com>
>
> +config TMS320C64X_GEMAC
> + tristate "TMS320C64X GEMAC Ethernet Driver Support"
> + depends on TMS320C64XPLUS
> + default n
> + help
> + This driver supports the C64X+ SoC family ethernet
> + interface.
> +
> source "drivers/net/sfc/Kconfig"
>
> source "drivers/net/benet/Kconfig"
> diff --git a/drivers/net/Makefile b/drivers/net/Makefile
> index 01b604a..d768fde 100644
> --- a/drivers/net/Makefile
> +++ b/drivers/net/Makefile
> @@ -259,6 +259,8 @@ obj-$(CONFIG_MLX4_CORE) += mlx4/
> obj-$(CONFIG_ENC28J60) += enc28j60.o
> obj-$(CONFIG_ETHOC) += ethoc.o
> obj-$(CONFIG_GRETH) += greth.o
> +obj-$(CONFIG_TMS320C64X_GEMAC) += gemac.o
> +gemac-objs := c6x_gemac.o c6x_gmdio.o
>
> obj-$(CONFIG_XTENSA_XT2000_SONIC) += xtsonic.o
>
> diff --git a/drivers/net/c6x_gemac.c b/drivers/net/c6x_gemac.c
> new file mode 100644
> index 0000000..40124df
> --- /dev/null
> +++ b/drivers/net/c6x_gemac.c
> @@ -0,0 +1,1582 @@
> +/*
> + * Port on Texas Instruments TMS320C6x architecture
> + *
> + * Copyright (C) 2006, 2007, 2008, 2009, 2010 Texas Instruments Incorporated
> + * Authors: Nicolas Videau ([email protected])
> + * Aurelien Jacquiot ([email protected])
> + *
> + * 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.
> + */

Add #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt

> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/delay.h>
> +#include <linux/interrupt.h>
> +#include <linux/init.h>
> +#include <linux/slab.h>
> +#include <linux/netdevice.h>
> +#include <linux/etherdevice.h>
> +#include <linux/skbuff.h>
> +#include <linux/spinlock.h>
> +#include <linux/timer.h>
> +#include <linux/platform_device.h>
> +#include <linux/io.h>
> +
> +#include <asm/setup.h>
> +#include <asm/irq.h>
> +#include <asm/gmdio.h>
> +#include <asm/gemac.h>
> +
> +#undef EMAC_DEBUG
> +
> +#ifdef EMAC_DEBUG
> +#define DPRINTK(fmt, args...) printk(KERN_DEBUG "GEMAC: [%s] " fmt, __func__, ## args)

pr_debug(foo)

> +#define ASSERT(cond) if (!(cond)) DPRINTK("ASSERT %s FAILURE\n", # cond)
> +#else
> +#define ASSERT(cond)
> +#define DPRINTK(fmt, args...)
> +#endif
> +
> +static int emac_open(struct net_device *dev);
> +static int emac_close(struct net_device *dev);
> +static int emac_reset(struct net_device *dev, int reset_mode);
> +static void emac_set_modes(struct net_device *dev);
> +static void emac_fixup_modes(struct net_device *dev);
> +static void emac_reset_filter(struct net_device *dev,
> + int channel,
> + int reset_mode);
> +static void emac_set_filter(struct net_device *dev, int channel);
> +static int emac_reconfigure_device(struct net_device *dev);
> +
> +#ifdef EMAC_TIMER_TICK_MDIO
> +static struct timer_list emac_timer;
> +#endif
> +
> +static struct emac_config config = { 0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } };
> +
> +static int emac_shared;
> +static int emac_idx;
> +
> +inline long _hex_chartol(char c)
> +{
> + if (c >= '0' && c <= '9')
> + return c - '0';
> + if (c >= 'A' && c <= 'F')
> + return c - 'A' + 10;
> + if (c >= 'a' && c <= 'f')
> + return c - 'a' + 10;
> +
> + return -1;
> +}

kstrtol

> +
> +static unsigned long _hex_strtoul(const char *str, const char **end)
> +{
> + unsigned long ul = 0;
> + long ud;
> + while ((ud = _hex_chartol(*str)) >= 0) {
> + ul = (ul << 4) | ud;
> + str++;
> + }
> + *end = str;
> + return ul;
> +}

kstrtoul

> +
> +static int __init get_mac_addr_from_cmdline(char *str)
> +{
> + const char *start = (const char *) str;
> + const char *end;
> + int count;
> +
> + for (count = 0; count < 6; count++) {
> + config.enetaddr[count] = _hex_strtoul(start, &end);
> + if (end == start)
> + return 0;
> + if ((*end != ':') && (count != 5))
> + return 0;
> + start = end + 1;
> + }
> + return 1;
> +}
> +
> +__setup("emac_addr=", get_mac_addr_from_cmdline);
> +
> +static int __init set_emac_shared(char *str)
> +{
> + emac_shared = 1;
> + return 1;
> +}
> +
> +__setup("emac_shared", set_emac_shared);
> +
> +/*
> + * Get the device statistic
> + */
> +static struct net_device_stats *emac_get_stats(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + unsigned int reg;
> + unsigned int dummy;
> + int i;
> +
> + emac_set_stat(dev->stats.multicast, EMAC_RXMCASTFRAMES);
> + emac_set_stat(dev->stats.collisions, EMAC_TXCOLLISION);
> + emac_set_stat(dev->stats.rx_length_errors, EMAC_RXOVERSIZED);
> + emac_set_stat(dev->stats.rx_length_errors, EMAC_RXUNDERSIZED);
> + emac_set_stat(dev->stats.rx_crc_errors, EMAC_RXCRCERRORS);
> + emac_set_stat(dev->stats.rx_frame_errors, EMAC_RXALIGNCODEERRORS);
> + emac_set_stat(dev->stats.tx_carrier_errors, EMAC_TXCARRIERSLOSS);
> + emac_set_stat(dev->stats.tx_fifo_errors, EMAC_TXUNDERRUN);
> + emac_set_stat(dev->stats.tx_window_errors, EMAC_TXLATECOLL);
> +
> + /* ACK statistic by write-to-decrement */
> + reg = EMAC_RXGOODFRAMES;
> + for (i = 0; i < EMAC_NUM_STATREGS; i++) {
> + dummy = emac_get_reg(reg);
> + emac_set_reg(reg, dummy);
> + reg += 4;
> + }
> +
> + return &dev->stats;
> +}
> +
> +/*
> + * Receive packets
> + */
> +static int emac_rx(struct net_device *dev, struct emac_desc *desc_ack)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + volatile struct emac_desc *desc = ep->cur_rx;
> + ushort pkt_len;
> + u32 pkt_flags = desc->packet_flags_len & 0xffff0000;
> + int loop = 1;
> + struct sk_buff *skb, *skb_old;
> +
> + DPRINTK("%s: RX desc_ack = 0x%x, cur_rx = 0x%x, num = %d\n",
> + dev->name, desc_ack, desc, (desc_ack - desc));

netdev_dbg(dev, etc)

> +
> + if ((desc == desc_ack) && (desc->packet_flags_len == EMAC_DESC_FLAG_OWNER))
> + loop = 0;
> +
> + while (loop) {
> + skb_old = ep->rx_skbuff[ep->skb_rx_dirty];
> +
> + pkt_len = desc->packet_flags_len & EMAC_PACKET_LEN_MASK;
> + pkt_flags = desc->packet_flags_len & 0xffff0000;
> +
> + skb = netdev_alloc_skb_ip_align(dev, ep->packet_mtu);
> + if (skb != NULL) {
> + /* Prepare old sk_buff */
> + skb_old->dev = dev;
> + skb_put(skb_old, pkt_len);
> +
> + /* No coherency is assumed between EDMA and L2 cache */
> + L2_cache_block_invalidate((u32) desc->buff,
> + (u32) desc->buff + pkt_len);
> +
> + skb_old->protocol = eth_type_trans(skb_old, dev);
> +
> + /* Attach new sk_buff to RX ring */
> + desc->buff = (u8 *) skb->data;
> + ep->rx_skbuff[ep->skb_rx_dirty] = skb;
> +
> + DPRINTK("%s: receiving packet of %d len, proto 0x%x\n",
> + dev->name, pkt_len, skb->protocol);
> +
> + /* Give back old sk_buff */
> + netif_rx(skb_old);
> + dev->last_rx = jiffies;
> +
> + /* Fill statistic */
> + dev->stats.rx_packets++;
> + dev->stats.rx_bytes += pkt_len;
> + } else {
> + printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);

netdev_warn(dev, "Memory squeeze, dropping packet\n");

Maybe ratelimited too.

> + dev->stats.rx_dropped++;
> + }
> +
> + /* Update RX dirty */
> + if (ep->skb_rx_dirty >= RX_RING_MOD_MAX)
> + ep->skb_rx_dirty = 0;
> + else
> + ep->skb_rx_dirty = ep->skb_rx_dirty + 1;
> +
> + /* Descriptor is now available */
> + desc->buff_offset_len = ep->packet_mtu;
> + desc->packet_flags_len = EMAC_DESC_FLAG_OWNER;
> +
> + /* Check if it is the last descriptor which has been received */
> + if (desc == desc_ack)
> + loop = 0;
> +
> + /* Loop in the ring */
> + desc = HW_TO_PTR(desc->next);
> + }
> + ep->cur_rx = (struct emac_desc *) desc;
> +
> + /* Check if the receiver stopped */
> + if (pkt_flags & EMAC_DESC_FLAG_EOQ)
> + emac_set_reg(EMAC_RX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
> + PTR_TO_HW((u32) ep->cur_rx));
> +
> + return 0;
> +}
> +
> +/*
> + * Transmit packets ACK
> + */
> +static int emac_tx(struct net_device *dev, struct emac_desc *desc_ack)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + volatile struct emac_desc *desc = ep->dirty_tx;
> + int loop = 1;
> +
> + while (loop) {
> + DPRINTK("%s: TX desc_ack = 0x%x, desc = 0x%x, num = %d\n",
> + dev->name, desc_ack, desc, (desc_ack - desc));
> +
> + if (ep->tx_skbuff[ep->skb_tx_dirty] == NULL) {
> + printk(KERN_ERR "%s: SKB NULL desc =%p desc_ack =%p, skb_tx_dirty=%ld count=%ld\n",
> + dev->name, desc, desc_ack, ep->skb_tx_dirty, ep->count_tx);

netdev_err("SKB NULL, etc...
Almost all of your printks should use netdev_<level>

> + break;
> + }
> +
> + /* Free the skbuff associated to this packet */
> + dev_kfree_skb_irq(ep->tx_skbuff[ep->skb_tx_dirty]);
> +
> + ep->tx_skbuff[ep->skb_tx_dirty] = NULL;
> + ep->skb_tx_dirty = (ep->skb_tx_dirty + 1) & TX_RING_MOD_MASK;
> + ep->count_tx--;
> +
> + /* Check if it is the last acknowledged descriptor */
> + if (desc++ == desc_ack)
> + loop = 0;
> +
> + /* Check end of the ring */
> + if (desc > ep->tx_desc_base + (TX_RING_SIZE - 1))
> + desc = ep->tx_desc_base;
> + }
> +
> + if (netif_running(dev))
> + netif_wake_queue(dev);
> +
> + /* Since we have freed up a buffer, the ring is no longer full */
> + if (ep->tx_full) {
> + ep->tx_full = 0;
> +
> + DPRINTK("%s: wake up queue count_tx = %d cur_tx = 0x%x head_tx\n",
> + dev->name, ep->count_tx, ep->cur_tx, ep->head_tx);
> +
> + if (netif_queue_stopped(dev))
> + netif_wake_queue(dev);
> + }
> +
> + /* If this is the end of the queue */
> + if (desc_ack->packet_flags_len & EMAC_DESC_FLAG_EOQ) {
> +
> + /* If there are some waiting packets, start the new queue */
> + if (ep->count_tx > 0)
> + emac_set_reg(EMAC_TX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
> + PTR_TO_HW(ep->head_tx));
> +
> + /* Set the new head */
> + ep->head_tx = ep->cur_tx;
> + }
> +
> + /* Update dirty tx */
> + ep->dirty_tx = (struct emac_desc *) desc;
> +
> + return NETDEV_TX_OK;
> +}
> +
> +/*
> + * Transmit the content of a skbuff
> + */
> +static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + volatile struct emac_desc *desc;
> + volatile struct emac_desc *prev_desc = NULL;
> + ushort pkt_len = skb->len;
> + unsigned long flags;
> +
> + if (ep->tx_full) {
> + printk(KERN_WARNING "%s: tx queue full\n", dev->name);
> + dev->stats.tx_dropped++;
> + return NETDEV_TX_BUSY;
> + }
> +
> + /* Pad short frame */
> + if (unlikely(pkt_len < ETH_ZLEN)) {
> + if (skb_padto(skb, ETH_ZLEN)) {
> + netif_wake_queue(dev);
> + return NETDEV_TX_OK;
> + }
> + pkt_len = ETH_ZLEN;
> + }
> +
> + spin_lock_irqsave(&ep->lock, flags);
> +
> + desc = ep->cur_tx;
> +
> + /* Set buffer length and pointer */
> + desc->buff = skb->data;
> + desc->packet_flags_len = pkt_len;
> + desc->buff_offset_len = pkt_len;
> + desc->next = NULL; /* close the queue*/
> +
> + /* No coherency is assumed between EDMA and L2 cache */
> + L2_cache_block_writeback((u32) skb->data,
> + (u32) skb->data + pkt_len);
> +
> + DPRINTK("%s: sending packet of %d len, skb_cur = %x, buffer = 0x%x\n",
> + dev->name, pkt_len, ep->skb_cur, skb->data);
> +
> + /* Save skb */
> + ep->tx_skbuff[ep->skb_cur] = skb;
> + ep->skb_cur = (ep->skb_cur + 1) & TX_RING_MOD_MASK;
> + dev->stats.tx_packets++;
> + dev->stats.tx_bytes += pkt_len;
> + dev->trans_start = jiffies;
> +
> + desc->packet_flags_len |= EMAC_DESC_FLAG_SOP
> + | EMAC_DESC_FLAG_EOP
> + | EMAC_DESC_FLAG_OWNER;
> +
> + /* Get the previous element of the ring if we are not the head */
> + if (desc != ep->head_tx) {
> + if (desc == ep->tx_desc_base)
> + prev_desc = ep->tx_desc_base + (TX_RING_SIZE - 1);
> + else
> + prev_desc = desc - 1;
> +
> + /* Link the buffer to the previous one in the list */
> + prev_desc->next = (struct emac_desc *) PTR_TO_HW(desc);
> + }
> +
> + ep->count_tx++;
> +
> + /* Update current pointer */
> + ep->cur_tx = (struct emac_desc *) desc + 1;
> +
> + /* Check end of ring */
> + if (ep->cur_tx > ep->tx_desc_base + (TX_RING_SIZE - 1))
> + ep->cur_tx = ep->tx_desc_base;
> +
> + /*
> + * If we are the new head and there is no descriptor to acknowledge, start
> + * the new head.
> + */
> + if ((desc == ep->head_tx) && (ep->count_tx == 1)) {
> + emac_set_reg(EMAC_TX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
> + PTR_TO_HW(ep->head_tx));
> + ep->head_tx = ep->cur_tx; /* set the new head */
> + }
> +
> + /* Check ring oll over: do not reach the not yet acknowledged packets */
> + if (ep->count_tx == TX_RING_SIZE) {
> + ep->tx_full = 1;
> +
> + DPRINTK("%s: tx queue full count_tx = %d cur_tx = 0x%x head_tx\n",
> + dev->name, ep->count_tx, ep->cur_tx, ep->head_tx);
> +
> + netif_stop_queue(dev);
> + }
> + spin_unlock_irqrestore(&ep->lock, flags);
> +
> + return NETDEV_TX_OK;
> +}
> +
> +static void emac_handle_host_interrupt(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + unsigned long status;
> +
> + /* Handle host error */
> + status = emac_get_reg(EMAC_MACSTATUS);
> +
> + /* Check if the problem occurs on our channel when we are slave */
> + if ((ep->slave)
> + && (((status & EMAC_M_RXERRCH) >> EMAC_S_RXERRCH) != IDX_TO_CHAN(emac_idx))
> + && (((status & EMAC_M_TXERRCH) >> EMAC_S_TXERRCH) != IDX_TO_CHAN(emac_idx)))
> + return;
> +
> + if ((status & EMAC_M_RXERRCODE) == (EMAC_V_OWNERSHIP << EMAC_S_RXERRCODE)) {
> + printk(KERN_ERR "%s: EMAC rx ring full\n", dev->name);
> + dev->stats.rx_fifo_errors++;
> + } else
> + printk(KERN_ERR "%s: EMAC fatal host error 0x%lx\n",
> + dev->name, status);
> +
> + DPRINTK(KERN_ERR "%s: Error head=%p desc=%p dirty=%p skb_tx_dirty=%ld count=%ld\n",
> + dev->name, ep->head_tx, ep->cur_tx,
> + ep->dirty_tx, ep->skb_tx_dirty, ep->count_tx);
> +
> + if (!ep->slave) {
> + /* Reconfigure the device */
> + ep->fatal_error = 1;
> + emac_reconfigure_device(dev);
> + }
> +}
> +
> +/*
> + * Receive EMAC interrupt management
> + */
> +
> +#ifdef EMAC_HAS_SEPARATE_RXTX_IRQS
> +
> +static irqreturn_t emac_rx_interrupt(int irq, void *netdev_id)
> +{
> + struct net_device *dev = netdev_id;
> + struct emac_private *ep = netdev_priv(dev);
> + struct emac_desc *desc;
> + unsigned long irq_flags;
> +
> + ectl_arch_rx_irq_enter(IDX_TO_CHAN(emac_idx));
> +
> + irq_flags = emac_arch_get_int_vector();
> +
> + if (irq_flags & EMAC_B_STATPEND)
> + (void) emac_get_stats(dev);
> +
> + if (irq_flags & EMAC_B_HOSTPEND)
> + emac_handle_host_interrupt(dev);
> +
> + if (emac_arch_get_pending_irq(irq_flags,
> + EMAC_B_RXPEND0,
> + IDX_TO_CHAN(emac_idx))) {
> +
> + /* ACK the interrupt */
> + desc = (struct emac_desc *) emac_get_reg(EMAC_RX0INTACK
> + + (IDX_TO_CHAN(emac_idx) << 2));
> + emac_set_reg(EMAC_RX0INTACK + (IDX_TO_CHAN(emac_idx) << 2), desc);
> +
> + /* Handle receive event */
> + emac_rx(netdev_id, HW_TO_PTR(desc));
> + }
> +
> + ectl_arch_rx_irq_leave(IDX_TO_CHAN(emac_idx));
> +
> + return IRQ_HANDLED;
> +}
> +
> +/*
> + * Transmit EMAC interrupt management
> + */
> +static irqreturn_t emac_tx_interrupt(int irq, void *netdev_id)
> +{
> + struct net_device *dev = netdev_id;
> + struct emac_private *ep = netdev_priv(dev);
> + struct emac_desc *desc;
> + unsigned long irq_flags;
> +
> + ectl_arch_tx_irq_enter(IDX_TO_CHAN(emac_idx));
> +
> + irq_flags = emac_arch_get_int_vector();
> +
> + if (irq_flags & EMAC_B_STATPEND)
> + (void) emac_get_stats(dev);
> +
> + if (irq_flags & EMAC_B_HOSTPEND)
> + emac_handle_host_interrupt(dev);
> +
> + if (emac_arch_get_pending_irq(irq_flags,
> + EMAC_B_TXPEND0,
> + IDX_TO_CHAN(emac_idx))) {
> +
> + /* ACK the interrupt */
> + desc = (struct emac_desc *) emac_get_reg(EMAC_TX0INTACK
> + + (IDX_TO_CHAN(emac_idx) << 2));
> + emac_set_reg(EMAC_TX0INTACK + (IDX_TO_CHAN(emac_idx) << 2), desc);
> +
> + /* Handle transmit ACK event */
> + emac_tx(netdev_id, HW_TO_PTR(desc));
> + }
> +
> + ectl_arch_tx_irq_leave(IDX_TO_CHAN(emac_idx));
> +
> + return IRQ_HANDLED;
> +}
> +
> +#else
> +
> +/*
> + * Main EMAC interrupt management
> + */
> +static irqreturn_t emac_interrupt(int irq, void *netdev_id)
> +{
> + struct net_device *dev = netdev_id;
> + struct emac_private *ep = netdev_priv(dev);
> + struct emac_desc *desc;
> + unsigned long irq_flags;
> +
> + /* Disable EMAC/MDIO interrupts */
> + emac_clearbit_reg(EMAC_EWCTL, EMAC_B_INTEN);
> +
> + irq_flags = emac_get_reg(EMAC_MACINVECTOR);
> +
> + if (irq_flags & EMAC_B_STATPEND)
> + (void) emac_get_stats(dev);
> +
> + if (irq_flags & EMAC_B_HOSTPEND) {
> + emac_handle_host_interrupt(dev);
> +
> + /* EMAC/MDIO interrupts already enabled by emac_open() */
> + return IRQ_HANDLED;
> + }
> +
> + if (irq_flags & EMAC_B_TXPEND0) {
> + /* ACK the interrupt */
> + desc = (struct emac_desc *) emac_get_reg(EMAC_TX0INTACK);
> + emac_set_reg(EMAC_TX0INTACK, desc);
> +
> + /* Handle transmit ACK event */
> + emac_tx(netdev_id, desc);
> + }
> +
> + if (irq_flags & EMAC_B_RXPEND0) {
> + /* ACK the interrupt */
> + desc = (struct emac_desc *) emac_get_reg(EMAC_RX0INTACK);
> + emac_set_reg(EMAC_RX0INTACK, desc);
> +
> + /* Handle receive event */
> + emac_rx(netdev_id, desc);
> + }
> +
> + /* Enable EMAC/MDIO interrupts */
> + emac_setbit_reg(EMAC_EWCTL, EMAC_B_INTEN);
> +
> + return IRQ_HANDLED;
> +}
> +#endif
> +
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> +/*
> + * EMAC poll
> + */
> +static void emac_poll(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + ectl_arch_disable_irq(IDX_TO_CHAN(emac_idx));
> +
> +#ifdef EMAC_HAS_SEPARATE_RXTX_IRQS
> + emac_tx_interrupt(dev->irq + 1, dev);
> + emac_rx_interrupt(dev->irq, dev);
> +#else
> + emac_interrupt(dev->irq, dev);
> +#endif
> +
> + ectl_arch_enable_irq(IDX_TO_CHAN(emac_idx), !ep->slave);
> +}
> +#endif
> +
> +/*
> + * Register the MAC address
> + */
> +
> +static void emac_register_mac_addr(struct net_device *dev, int idx)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + u32 val;
> + int i;
> +
> + /* Copy the config MAC address to the dev_addr */
> + for (i = 4; i >= 0; i--)
> + dev->dev_addr[i] = config.enetaddr[i];
> + /*
> + * Compute MAC addr low for all for the given EMAC instances if several.
> + * Each device consume n MAC addresses where n is the number cores.
> + * This value is for GEM0, this value + 2 is for GEM1, etc
> + * The number programmed in this field will be incremented by n * 2 from
> + * device to device
> + */
> + dev->dev_addr[5] = (config.enetaddr[5] +
> + (IDX_TO_MAC(idx)) + DEV_TO_MAC(dev->dev_id)) & 0xff;
> +
> + /* Choose MAC address index between 0 and 31 */
> + emac_arch_set_mac_addr_index(idx);
> +
> + /* Compute and store MAC addr high */
> + val = 0;
> + for (i = 3; i >= 0; i--)
> + val = (val << 8) | dev->dev_addr[i];

Inconsistent style with low portion below
and function emac_reset.

This might be better as:

val = (dev->dev_addr[3] << 24) |
(dev->dev_addr[2] << 16) |
(dev->dev_addr[1] << 8) |
(dev->dev_addr[0] << 0);

> + emac_arch_set_mac_addr_high(val);
> +
> + val = (dev->dev_addr[5] << 8) | dev->dev_addr[4];


> + val |= (1 << EMAC_S_VALID)
> + | (1 << EMAC_S_MATCHFILTER)
> + | (IDX_TO_CHAN(idx) << EMAC_S_CHANNEL);
> +
> + emac_arch_set_mac_addr_low(val);
> +}
> +
> +/*
> + * Reset the EMAC software ring.
> + */
> +static void emac_reset_ring(struct emac_private *ep)
> +{
> + struct emac_desc *desc;
> + int i;
> +
> + desc = (struct emac_desc *) ep->emac_dsc_base;
> +
> + /* Reset rx ring */
> + ep->cur_rx = desc;
> + ep->skb_rx_dirty = 0;
> +
> + for (i = 0; i < RX_RING_SIZE; desc++, i++)
> + desc->packet_flags_len = EMAC_DESC_FLAG_OWNER;
> +
> + /* Reset tx ring */
> + desc = (struct emac_desc *) (ep->emac_dsc_base + (RX_RING_SIZE << 4));
> + ep->cur_tx = desc;
> + ep->dirty_tx = desc;
> + ep->head_tx = desc;
> + ep->skb_cur = 0;
> + ep->skb_tx_dirty = 0;
> + ep->tx_full = 0;
> + ep->fatal_error = 0;
> + ep->count_tx = 0;
> +
> + for (i = 0; i < TX_RING_SIZE; i++) {
> + desc->buff = NULL;
> + desc->buff_offset_len = 0;
> + desc->packet_flags_len = 0;
> + desc->next = NULL;
> + ep->tx_skbuff[i] = NULL;

memset?

> + desc++;
> + }
> +}
> +
> +/*
> + * Reconfigure the EMAC device
> + */
> +static int emac_reconfigure_device(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + if (!ep->slave) {
> + unsigned int hash1;
> + unsigned int hash2;
> + unsigned int promisc;
> + unsigned int control;
> + unsigned int rx_intmask;
> + unsigned int tx_intmask;
> + unsigned int unicast;
> + unsigned int *mac_ctx;
> + int i;
> +
> + /* Get state */
> + hash1 = emac_arch_get_hash1();
> + hash2 = emac_arch_get_hash2();
> + promisc = emac_arch_get_promisc();
> + control = emac_arch_get_control();
> +
> + unicast = emac_get_reg(EMAC_RXUNICASTSET);
> + rx_intmask = emac_get_reg(EMAC_RXINTMASKSET);
> + tx_intmask = emac_get_reg(EMAC_TXINTMASKSET);
> +
> + /* Save MAC addresses */
> + mac_ctx = kmalloc((sizeof(u32) << 1) * MAC_ADDR_NUM, GFP_KERNEL);
> + for (i = 0; i < MAC_ADDR_NUM; i++) {
> + emac_arch_set_mac_addr_index(i);
> + mac_ctx[i << 1] = emac_arch_get_mac_addr_high();
> + mac_ctx[(i << 1) + 1] = emac_arch_get_mac_addr_low();
> + }
> +
> + /* Reset the EMAC */
> + if (netif_running(dev)) {
> + emac_close(dev);
> + emac_reset(dev, GEMAC_RESET_WARM);
> + emac_open(dev);
> + } else {
> + emac_reset(dev, GEMAC_RESET_WARM);
> + }
> +
> + /* Restore MAC addresses */
> + for (i = 0; i < MAC_ADDR_NUM; i++) {
> + emac_arch_set_mac_addr_index(i);
> + emac_arch_set_mac_addr_high(mac_ctx[i << 1]);
> + emac_arch_set_mac_addr_low(mac_ctx[(i << 1) + 1]);
> + }
> + kfree(mac_ctx);
> +
> + /* Restore state */
> + emac_arch_set_hash1(hash1);
> + emac_arch_set_hash2(hash2);
> + emac_arch_set_promisc(hash2);
> + emac_arch_set_control(hash2);
> +
> + emac_set_reg(EMAC_RXINTMASKSET, rx_intmask);
> + emac_set_reg(EMAC_TXINTMASKSET, tx_intmask);
> + emac_set_reg(EMAC_RXUNICASTSET, unicast);
> + } else
> + /* Only master core can reset the device */
> + return -EBUSY;
> +
> + return 0;
> +}
> +
> +/*
> + * Reset the EMAC hardware.
> + */
> +static int emac_reset(struct net_device *dev, int reset_mode)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + volatile u32 *preg;

volatile?

> + int i;
> +
> + if (!ep->slave) {
> +
> + if (reset_mode == GEMAC_RESET_COLD) {
> + /* Reset integrated switch if any */
> + emac_arch_reset_switch();
> +
> + /* Reset EMAC control Module */
> + emac_arch_reset_ectl();
> + }
> +
> + /* Reset EMAC */
> + emac_setbit_reg(EMAC_SOFTRESET, EMAC_B_SOFTRST);
> +
> + /* Wait until reset has occured or timeout */
> + for (i = 0; i <= HZ / 2; i++) {
> + if (emac_get_reg(EMAC_SOFTRESET) == 0x0)
> + break;
> + if (i == HZ / 2)
> + return 1;
> + msleep_interruptible(1);
> + }
> + }
> +
> + /* Set interrupt pacing */
> + emac_arch_set_pacing();
> +
> + if (!ep->slave) {
> + /* Reset MAC, TX, RX Control */
> + emac_set_reg(EMAC_MACCONTROL, 0);
> + emac_set_reg(EMAC_TXCONTROL, 0);
> + emac_set_reg(EMAC_RXCONTROL, 0);
> +
> + if (reset_mode == GEMAC_RESET_COLD) {
> +#ifdef EMAC_DO_INIT_MDIO
> + /* MII/MDIO setup */
> + mdio_init(emac_get_reg(EMAC_TXIDVER));
> +#endif
> +
> + /* Init HDPs to NULL for all channels */
> + emac_set_reg(EMAC_TX0HDP, 0);
> + emac_set_reg(EMAC_TX1HDP, 0);
> + emac_set_reg(EMAC_TX2HDP, 0);
> + emac_set_reg(EMAC_TX3HDP, 0);
> + emac_set_reg(EMAC_TX4HDP, 0);
> + emac_set_reg(EMAC_TX5HDP, 0);
> + emac_set_reg(EMAC_TX6HDP, 0);
> + emac_set_reg(EMAC_TX7HDP, 0);
> + emac_set_reg(EMAC_RX0HDP, 0);
> + emac_set_reg(EMAC_RX1HDP, 0);
> + emac_set_reg(EMAC_RX2HDP, 0);
> + emac_set_reg(EMAC_RX3HDP, 0);
> + emac_set_reg(EMAC_RX4HDP, 0);
> + emac_set_reg(EMAC_RX5HDP, 0);
> + emac_set_reg(EMAC_RX6HDP, 0);
> + emac_set_reg(EMAC_RX7HDP, 0);
> +
> + /* Clear statistic registers */
> + if (reset_mode == GEMAC_RESET_COLD) {
> + preg = emac_addr_reg(EMAC_RXGOODFRAMES);
> + for (i = 0; i < EMAC_NUM_STATREGS; i++)
> + *preg++ = 0;
> + }
> +
> + /* Clear all MAC addresses */
> + emac_arch_clear_mac_addr();
> + }
> + }
> +
> + /* Register my MAC address */
> + emac_register_mac_addr(dev, emac_idx);
> +
> + if (!ep->slave) {
> +
> + /* Used for pause frame (IEEE 802.3x) but not working for MC */
> + emac_set_reg(EMAC_MACSRCADDRLO,
> + (dev->dev_addr[0] << 8) | dev->dev_addr[1]);
> + emac_set_reg(EMAC_MACSRCADDRHI,
> + (dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
> + (dev->dev_addr[4] << 8) | (dev->dev_addr[5]));
> +
> + if (reset_mode == GEMAC_RESET_COLD) {
> +
> + /* Init completion pointers to NULL */
> + emac_set_reg(EMAC_RX0INTACK, 0x0);
> + emac_set_reg(EMAC_RX1INTACK, 0x0);
> + emac_set_reg(EMAC_RX2INTACK, 0x0);
> + emac_set_reg(EMAC_RX3INTACK, 0x0);
> + emac_set_reg(EMAC_RX4INTACK, 0x0);
> + emac_set_reg(EMAC_RX5INTACK, 0x0);
> + emac_set_reg(EMAC_RX6INTACK, 0x0);
> + emac_set_reg(EMAC_RX7INTACK, 0x0);
> + emac_set_reg(EMAC_TX0INTACK, 0x0);
> + emac_set_reg(EMAC_TX1INTACK, 0x0);
> + emac_set_reg(EMAC_TX2INTACK, 0x0);
> + emac_set_reg(EMAC_TX3INTACK, 0x0);
> + emac_set_reg(EMAC_TX4INTACK, 0x0);
> + emac_set_reg(EMAC_TX5INTACK, 0x0);
> + emac_set_reg(EMAC_TX6INTACK, 0x0);
> + emac_set_reg(EMAC_TX7INTACK, 0x0);
> + }
> +
> + /* Reset unicast, multicast, broadcast Rx */
> + emac_reset_filter(dev, IDX_TO_CHAN(emac_idx), reset_mode);
> +
> + /* Set device modes */
> + emac_set_modes(dev);
> +
> + /* Disable all channel interrupts */
> + if (reset_mode == GEMAC_RESET_COLD) {
> + emac_set_reg(EMAC_RXINTMASKCLEAR, 0xff);
> + emac_set_reg(EMAC_TXINTMASKCLEAR, 0xff);
> + }
> +
> + /* Enable host and stat interrupts */
> + emac_set_reg(EMAC_MACINTMASKSET, EMAC_B_HOSTINT | EMAC_B_STATINT);
> + } else {
> + /* Fixup mode according to hw configuration */
> + emac_fixup_modes(dev);
> + }
> +
> + /* Enable TX and RX interrupts for a given channel */
> + emac_arch_enable_irq(EMAC_TXINTMASKSET, IDX_TO_CHAN(emac_idx));
> + emac_arch_enable_irq(EMAC_RXINTMASKSET, IDX_TO_CHAN(emac_idx));
> +
> + /* Reset transmit/receive buffers */
> + if (reset_mode == GEMAC_RESET_WARM)
> + (void) emac_reset_ring(ep);
> +
> + /* Set default receive filter: unicast, multicast and broadcast */
> + emac_set_filter(dev, IDX_TO_CHAN(emac_idx));
> +
> + return 0;
> +}
> +
> +/*
> + * Open the device
> + */
> +static int emac_open(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + if (!ep->slave) {
> + /* Set MAC mode (Gigabyte, xxMII, pacing, etc) */
> + emac_arch_init_control(ep->mode_flags & EMAC_CONFIG_PACING);
> +
> + /* Enable RX and TX */
> + emac_set_reg(EMAC_TXCONTROL, 1);
> + emac_set_reg(EMAC_RXCONTROL, 1);
> + }
> +
> + /* Ready for RX */
> + emac_set_reg(EMAC_RX0HDP + (IDX_TO_CHAN(emac_idx) << 2),
> + PTR_TO_HW(ep->cur_rx));
> +
> + /* Enable interrupts at the ECTL level (misc int only for master) */
> + ectl_arch_enable_irq(IDX_TO_CHAN(emac_idx), !ep->slave);
> +
> + netif_start_queue(dev);
> +
> + return 0;
> +}
> +
> +/*
> + * Close the device
> + */
> +static int emac_close(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + netif_stop_queue(dev);
> +
> + /* Disable interrupt at the ECTL level */
> + ectl_arch_disable_irq(IDX_TO_CHAN(emac_idx));
> +
> + /* Teardown RX and TX */
> + emac_set_reg(EMAC_RXTEARDOWN, IDX_TO_CHAN(emac_idx));
> + emac_set_reg(EMAC_TXTEARDOWN, IDX_TO_CHAN(emac_idx));
> +
> + if (!ep->fatal_error) {
> + unsigned int tmp;
> +
> + /* Wait for the teardown to complete */
> + for (tmp = 0; tmp != 0xfffffffc;
> + tmp = emac_get_reg(EMAC_RX0INTACK + \

Don't use line continuations unnecessarily please.

> + (IDX_TO_CHAN(emac_idx) << 2)))
> + emac_set_reg(EMAC_RX0INTACK + \
> + (IDX_TO_CHAN(emac_idx) << 2), tmp);
> +
> + for (tmp = 0; tmp != 0xfffffffc;
> + tmp = emac_get_reg(EMAC_TX0INTACK + \
> + (IDX_TO_CHAN(emac_idx) << 2)))
> + emac_set_reg(EMAC_TX0INTACK + \
> + (IDX_TO_CHAN(emac_idx) << 2), tmp);
> + }
> +
> + if (!ep->slave) {
> + /* Disable Rx, Tx and MII */
> + emac_set_reg(EMAC_TXCONTROL, 0);
> + emac_set_reg(EMAC_RXCONTROL, 0);
> + emac_set_reg(EMAC_MACCONTROL, 0);
> + }
> +
> + /* Clean up the software ring */
> + emac_reset_ring(ep);
> +
> + return 0;
> +}
> +
> +/*
> + * Initialize the EMAC software ring.
> + * For the rx ring, we initialize the packet descriptors with pre-allocated
> + * skbuff to the packet MTU size.
> + * For the tx ring, we only initialize it with NULL values.
> + */
> +static int emac_setup_ring(struct emac_private *ep)
> +{
> + struct emac_desc *desc;
> + int i;
> + struct sk_buff *skb;
> +
> + /* Setup rx ring*/
> + desc = (struct emac_desc *) ep->emac_dsc_base;
> + ep->rx_desc_base = desc;
> + ep->cur_rx = desc;
> + ep->skb_rx_dirty = 0;
> +
> + /* Allocate ring buffers via sk buffers */
> + for (i = 0; i < RX_RING_SIZE; i++) {
> + skb = netdev_alloc_skb_ip_align(ep->dev, ep->packet_mtu);
> + if (!skb)
> + return 1;
> +
> + ep->rx_skbuff[i] = skb;
> + desc->buff = (u8 *) skb->data;
> + desc->buff_offset_len = ep->packet_mtu;
> + desc->packet_flags_len = EMAC_DESC_FLAG_OWNER;
> + desc->next = PTR_TO_HW(desc + 1);
> + desc++;
> + }
> +
> + /* Loop the ring */
> + (desc - 1)->next = PTR_TO_HW(ep->rx_desc_base);
> +
> + /* Setup tx ring */
> + desc = (struct emac_desc *) (ep->emac_dsc_base + (RX_RING_SIZE << 4));
> + ep->tx_desc_base = desc;
> + ep->cur_tx = desc;
> + ep->dirty_tx = desc;
> + ep->head_tx = desc;
> + ep->skb_cur = 0;
> + ep->skb_tx_dirty = 0;
> + ep->tx_full = 0;
> + ep->fatal_error = 0;
> + ep->count_tx = 0;
> +
> + for (i = 0; i < TX_RING_SIZE; i++) {
> + desc->buff = NULL;
> + desc->buff_offset_len = 0;
> + desc->packet_flags_len = 0;
> + desc->next = NULL;
> + ep->tx_skbuff[i] = NULL;
> + desc++;
> + }
> + return 0;
> +}
> +
> +/*
> + * Called by the kernel to send a packet out into the void
> + * of the net.
> + */
> +static void emac_timeout(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + printk(KERN_WARNING "%s: transmit timed out\n", dev->name);
> + dev->stats.tx_errors++;
> + dev->trans_start = jiffies;
> + if (!ep->tx_full)
> + netif_wake_queue(dev);
> +}
> +
> +/*
> + * Set or clear the multicast filter for this adaptor.
> + */
> +#ifdef EMAC_HAS_ALE_SUPPORT
> +static void emac_reset_filter(struct net_device *dev,
> + int channel,
> + int reset_mode)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + int i;
> +
> + if (reset_mode == GEMAC_RESET_COLD) {
> + /* Alloc mcast list */
> + ep->mcast_infos = kmalloc(3 * EMAC_V_ALE_MAX_MCAST, GFP_KERNEL);
> + /* Init mcast table */
> + if (ep->mcast_infos) {
> + memset(ep->mcast_infos, 0x0, 3 * EMAC_V_ALE_MAX_MCAST);
> + /* Clear device multicast list */
> + for (i = 0; i < EMAC_V_ALE_MAX_MCAST; i++) {
> + emac_set_reg(EMAC_ALETBLW0, 0);
> + emac_set_reg(EMAC_ALETBLW1, 0);
> + emac_set_reg(EMAC_ALETBLW2, 0);
> + emac_set_reg(EMAC_ALETBLCTL,
> + i | EMAC_B_ALE_WRITE_RDZ);
> + }
> + }
> + }
> + if ((reset_mode == GEMAC_RESET_WARM) && (ep->mcast_infos)) {
> + /* Re-set device multicast list */
> + for (i = 0; i < ep->mcast_valid_len; i++) {
> + emac_set_reg(EMAC_ALETBLW0, ep->mcast_infos[3*i]);
> + emac_set_reg(EMAC_ALETBLW1, ep->mcast_infos[3*i+1]);
> + emac_set_reg(EMAC_ALETBLW2, ep->mcast_infos[3*i+2]);
> + emac_set_reg(EMAC_ALETBLCTL,
> + i | EMAC_B_ALE_WRITE_RDZ);
> + }
> + /* Set mcast mode if needed */
> + if (ep->mcast_valid_len)
> + emac_setbit_reg(EMAC_ALEUNKNOWNVLAN,
> + EMAC_B_REG_MCAST_FLOOD_ON);
> + }
> +}
> +
> +static void emac_set_modes(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + if (ep->mode_flags & EMAC_CONFIG_RXCRC)
> + ep->packet_mtu = PKT_MTU_CRC;
> + else
> + ep->packet_mtu = PKT_MTU_NOCRC;
> +
> + /* If PASSERROR is set, enable both ERROR and short frames */
> + if (ep->mode_flags & EMAC_CONFIG_PASSERROR)
> + emac_setbit_reg(EMAC_MACCONTROL,
> + EMAC_B_RXCEFEN | EMAC_B_RXCSFEN);
> +
> + /* If PASSCONTROL is set, enable control frames */
> + if (ep->mode_flags & EMAC_CONFIG_PASSCONTROL)
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_RXCMFEN);
> +
> + /* Set MAC loopback if requested */
> + if (ep->mode_flags & EMAC_CONFIG_MACLOOPBACK)
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_LOOPBACK);
> +}
> +
> +static void emac_set_filter(struct net_device *dev, int channel)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + emac_set_reg(CPSW_SW_CTL, 0x000000F4); /* Enable switch flow control */
> + emac_set_reg(CPSW_RX_CH_MAP, 0x11110000); /* RX switch priority */
> +
> + emac_set_reg(EMAC_ALECONTROL, 0x80000004); /* ALE enable and bypass */
> + emac_set_reg(EMAC_ALEPRESCALE, 0x0); /* no mcat/broadcast limit */
> + emac_set_reg(EMAC_ALEUNKNOWNVLAN, 0x07030307); /* need it!!! */
> + emac_set_reg(EMAC_ALEPORTCTL0, 0x3); /* Port 0 in forward state */
> + emac_set_reg(EMAC_ALEPORTCTL1, 0x3); /* Port 1 in forward state */
> + emac_set_reg(EMAC_ALEPORTCTL2, 0x3); /* Port 2 in forward state */
> +}
> +
> +static void emac_set_rx_mode(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + struct dev_mc_list *dmi = dev->mc_list;
> + u8 hashval, tmpval;
> + u32 info0, info1, info2;
> + int i;
> +
> + /* Only master can use promiscuous or multicast */
> + if (ep->slave)
> + return;
> +
> + if (dev->flags & IFF_PROMISC)
> + /* Set promiscuous mode */
> + emac_setbit_reg(EMAC_ALECONTROL, EMAC_B_ALEBYPASS);
> + else
> + /* Reset promiscuous mode */
> + emac_clearbit_reg(EMAC_ALECONTROL, EMAC_B_ALEBYPASS);
> +
> + /* Clear multicast config */
> + emac_clearbit_reg(EMAC_ALEUNKNOWNVLAN, EMAC_B_MCAST_FLOOD_ON |
> + EMAC_B_REG_MCAST_FLOOD_ON);
> +
> + /* Clear old multicast list that will not be reused */
> + for (i = dev->mc_count; i < ep->mcast_valid_len; i++) {
> + emac_setbit_reg(EMAC_ALETBLW0, 0);
> + emac_setbit_reg(EMAC_ALETBLW1, 0);
> + emac_setbit_reg(EMAC_ALETBLW2, 0);
> + emac_setbit_reg(EMAC_ALETBLCTL,
> + i | EMAC_B_ALE_WRITE_RDZ);
> + }
> +
> + if ((dev->flags & IFF_ALLMULTI) ||
> + (dev->mc_count > EMAC_V_ALE_MAX_MCAST)) {
> + /* Set all multicast */
> + emac_setbit_reg(EMAC_ALEUNKNOWNVLAN, EMAC_B_MCAST_FLOOD_ON |
> + EMAC_B_REG_MCAST_FLOOD_ON);
> + } else {
> + /* Set mcast from a list */
> + for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) {
> + u8 *p_dmi = dmi->dmi_addr;
> +
> + info0 = (((p_dmi[2]&0x0ff)<<24) |
> + ((p_dmi[3]&0x0ff)<<16) |
> + ((p_dmi[4]&0x0ff)<<8) | ((p_dmi[5]&0x0ff)<<0));
> + info1 = ((3<<30) | (0<<29) | (1<<28) |
> + ((0&0x0fff)<<16) |
> + ((p_dmi[0]&0x0ff)<<8) | ((p_dmi[1]&0x0ff)<<0));
> + info2 = (0 << 3) | (7 & 0x7);
> +
> + /* Only support group multicast */
> + if (!(*p_dmi & 1)) {
> + /* don't use this entry */
> + info0 = 0;
> + info1 = 1;
> + info2 = 2;
> + }
> +
> + emac_set_reg(EMAC_ALETBLW0, info0);
> + emac_set_reg(EMAC_ALETBLW1, info1);
> + emac_set_reg(EMAC_ALETBLW2, info2);
> + emac_set_reg(EMAC_ALETBLCTL,
> + i | EMAC_B_ALE_WRITE_RDZ);
> +
> + /* Copy mcast list */
> + if (ep->mcast_infos) {
> + ep->mcast_infos[3*i] = info0;
> + ep->mcast_infos[3*i+1] = info1;
> + ep->mcast_infos[3*i+2] = info2;
> + }
> + }
> +
> + /* set multicast mode if needed */
> + if (dev->mc_count)
> + emac_setbit_reg(EMAC_ALEUNKNOWNVLAN,
> + EMAC_B_REG_MCAST_FLOOD_ON);
> +
> + /* Remember mcast valid addrs count */
> + ep->mcast_valid_len = dev->mc_count;
> + }
> +}
> +
> +#else /* !EMAC_HAS_ALE_SUPPORT */
> +
> +static void emac_reset_filter(struct net_device *dev,
> + int channel,
> + int reset_mode)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + /* Reset multicast hash table */
> + emac_set_reg(EMAC_MACHASH1, 0);
> + emac_set_reg(EMAC_MACHASH2, 0);
> +
> + /* Set buffer offset */
> + emac_set_reg(EMAC_RXBUFFEROFFSET, 0);
> +
> + /* Reset RX (M)ulticast (B)roadcast (P)romiscuous Enable register */
> + emac_set_reg(EMAC_RXMBPENABLE, 0);
> +
> + if (reset_mode == GEMAC_RESET_COLD) {
> + /* Clear unicast RX on channel 0-7 */
> + emac_set_reg(EMAC_RXUNICASTCLEAR, 0xff);
> + } else
> + emac_set_reg(EMAC_RXUNICASTCLEAR, (1 << channel));
> +}
> +
> +static void emac_fixup_modes(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + if (emac_get_reg(EMAC_RXMBPENABLE) & EMAC_B_RXPASSCRC)
> + ep->packet_mtu = PKT_MTU_CRC;
> + else
> + ep->packet_mtu = PKT_MTU_NOCRC;
> +}
> +
> +static void emac_set_modes(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + if (ep->slave)
> + return;
> +
> + if (ep->mode_flags & EMAC_CONFIG_RXCRC) {
> + emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXPASSCRC);
> + ep->packet_mtu = PKT_MTU_CRC;
> + } else
> + ep->packet_mtu = PKT_MTU_NOCRC;
> +
> + /* If PASSERROR is set, enable both ERROR and short frames */
> + if (ep->mode_flags & EMAC_CONFIG_PASSERROR)
> + emac_setbit_reg(EMAC_RXMBPENABLE,
> + EMAC_B_RXCEFEN | EMAC_B_RXCSFEN);
> +
> + /* If PASSCONTROL is set, enable control frames */
> + if (ep->mode_flags & EMAC_CONFIG_PASSCONTROL)
> + emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCMFEN);
> +
> + /* Set the channel configuration to priority if requested */
> + if (ep->mode_flags & EMAC_CONFIG_CHPRIORITY)
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_TXPTYPE);
> +
> + /* Set MAC loopback if requested */
> + if (ep->mode_flags & EMAC_CONFIG_MACLOOPBACK)
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_LOOPBACK);
> +}
> +
> +static void emac_set_filter(struct net_device *dev, int channel)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> +
> + /* Set unicast for the given channel */
> + emac_set_reg(EMAC_RXUNICASTSET, 1 << channel);
> +
> + if (!ep->slave) {
> + emac_set_reg(EMAC_RXMBPENABLE, 0);
> + emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_MULTEN);
> + emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_BROADEN);
> + emac_setbit_reg(EMAC_RXMBPENABLE, (channel | (channel << 8)));
> + }
> +}
> +
> +static void emac_set_rx_mode(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + struct netdev_hw_addr *ha;
> + u8 hashval, tmpval;
> + u32 machash1, machash2;
> + int i;
> +
> + /* Only master can use promiscuous or multicast */
> + if (ep->slave)
> + return;
> +
> + if (dev->flags & IFF_PROMISC) {
> + /* Set promiscuous mode */
> + emac_setbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN);
> + } else {
> + /* Reset promiscuous mode */
> + emac_clearbit_reg(EMAC_RXMBPENABLE, EMAC_B_RXCAFEN);
> + }
> +
> + if (dev->flags & IFF_ALLMULTI) {
> +
> + /* Set all multicast filter */
> + emac_setbit_reg(EMAC_MACHASH1, 0xffffffff);
> + emac_setbit_reg(EMAC_MACHASH2, 0xffffffff);
> +
> + } else {
> +
> + hashval = 0;
> + machash1 = 0;
> + machash2 = 0;
> +
> + netdev_for_each_mc_addr(ha, dev) {
> + u8 *addr = ha->addr;
> +
> + /* Only support group multicast */
> + if (!(*addr & 1))
> + continue;

I believe you don't need to test the multicast address again.
If you _really_ do, is_multicast_ether_addr.

> +
> + for (i = 0; i < 2; i++) {
> + tmpval = (u8) *addr++;
> + hashval ^= (u8) (tmpval >> 2) ^ (tmpval << 4);
> + tmpval = (u8) *addr++;
> + hashval ^= (u8) (tmpval >> 4) ^ (tmpval << 2);
> + tmpval = (u8) *addr++;
> + hashval ^= (u8) (tmpval >> 6) ^ (tmpval);
> + }
> +
> + if (hashval & 0x20)
> + machash2 |= (1 << (hashval & 0x1f));
> + else
> + machash1 |= (1 << (hashval & 0x1f));
> + }
> +
> + /* Set computed multicast filter */
> + emac_setbit_reg(EMAC_MACHASH1, machash1);
> + emac_setbit_reg(EMAC_MACHASH2, machash2);
> + }
> +}
> +#endif /* !EMAC_HAS_ALE_SUPPORT */
> +
> +#ifdef EMAC_TIMER_TICK_MDIO
> +/*
> + * This function should be called for each device in the system on a
> + * periodic basis of 100mS (10 times a second). It is used to check the
> + * status of the EMAC and MDIO device.
> + */
> +static void emac_timer_tick(unsigned long data)
> +{
> + struct net_device *dev = (struct net_device *)data;
> + struct emac_private *ep = netdev_priv(dev);
> + unsigned int link_status;
> + unsigned int link_event = mdio_timer_tick();
> + unsigned int intfmacsel = mdio_get_macsel();
> +
> + /*
> + * Signal the MDIO
> + */
> + if (link_event == MDIO_EVENT_LINKUP) {
> + link_status = mdio_get_status();
> + if (link_status == MDIO_LINKSTATUS_FD10 ||
> + link_status == MDIO_LINKSTATUS_FD100 ||
> + link_status == MDIO_LINKSTATUS_FD1000) {
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_FULLDUPLEX);
> + if (intfmacsel == DEVSTAT_MACSEL_RMII)
> + emac_setbit_reg(EMAC_MACCONTROL,
> + EMAC_B_RMIIDUPLEXMODE);
> + } else {
> + emac_clearbit_reg(EMAC_MACCONTROL, EMAC_B_FULLDUPLEX);
> + if (intfmacsel == DEVSTAT_MACSEL_RMII)
> + emac_clearbit_reg(EMAC_MACCONTROL,
> + EMAC_B_RMIIDUPLEXMODE);
> + }
> +
> + if (link_status == MDIO_LINKSTATUS_FD1000)
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_GIG);
> +
> + if ((link_status == MDIO_LINKSTATUS_FD10 ||
> + link_status == MDIO_LINKSTATUS_HD10) &&
> + (intfmacsel == DEVSTAT_MACSEL_RMII))
> + /* Clear bit to set clock to 2.5 MHz */
> + emac_clearbit_reg(EMAC_MACCONTROL, EMAC_B_RMIISPEED);
> +
> + if ((link_status == MDIO_LINKSTATUS_FD100 ||
> + link_status == MDIO_LINKSTATUS_HD100) &&
> + (intfmacsel == DEVSTAT_MACSEL_RMII))
> + /* Set bit to set clock to 25 MHz */
> + emac_setbit_reg(EMAC_MACCONTROL, EMAC_B_RMIISPEED);
> +
> + /* eventually call platform hook for RMII out of reset */
> + rmii_arch_fix();
> +
> + /* Put RGMII in forced link mode */
> + if (intfmacsel == DEVSTAT_MACSEL_RGMII)
> + emac_clearbit_reg(EMAC_MACCONTROL, EMAC_B_RGMIIEN);
> + }
> + mod_timer(&emac_timer, jiffies + EMAC_TIMER_PERIOD);
> +}
> +#endif /* EMAC_TIMER_TICK_MDIO */
> +
> +static const char emac_driver_name[] = "EMAC";

EMAC? Shouldn't this be c6x_gmac?

> +static const struct net_device_ops gemac_netdev_ops = {
> + .ndo_open = emac_open,
> + .ndo_stop = emac_close,
> + .ndo_start_xmit = emac_start_xmit,
> + .ndo_tx_timeout = emac_timeout,
> + .ndo_set_multicast_list = emac_set_rx_mode,
> + .ndo_set_mac_address = eth_mac_addr,
> + .ndo_get_stats = emac_get_stats,
> +#ifdef CONFIG_NET_POLL_CONTROLLER
> + .ndo_poll_controller = emac_poll,
> +#endif
> + .ndo_change_mtu = eth_change_mtu,
> + .ndo_validate_addr = eth_validate_addr,
> +};
> +
> +static const struct ethtool_ops gemac_ethtool_ops = {
> +};
> +
> +static int __init emac_probe(struct platform_device *pdev)
> +{
> + struct net_device *netdev;
> + struct emac_private *ep;
> + int res = -EINVAL;
> + int i;
> +#ifdef EMAC_ARCH_HAS_MAC_ADDR
> + char hw_emac_addr[6];
> +#endif
> + struct resource *cur_res;
> + static int ndevs;
> + int irq = 0;
> +
> + emac_idx = get_emac_idx();
> +
> + if (ndevs >= EMAC_MAX_INSTANCE) {
> + printk(KERN_ERR "gemac: Invalid instance: %d (max=%d)\n",
> + ndevs, EMAC_MAX_INSTANCE);

pr_err("Invalid instance: %d (max=%d)\n",
ndevs, EMAC_MAX_INSTANCE);

> + return -EINVAL;
> + }
> +
> + /* Allocate private information */
> + netdev = alloc_etherdev(sizeof(struct emac_private));
> + if (!netdev)
> + return -ENOMEM;
> +
> + SET_NETDEV_DEV(netdev, &pdev->dev);
> +
> + ep = netdev_priv(netdev);
> + ep->dev = netdev;
> +
> + spin_lock_init(&ep->lock);
> +
> + /* Get irqs numbers */
> + cur_res = platform_get_resource_byname(pdev, IORESOURCE_IRQ, "IRQ_SRC");
> + if (cur_res)
> + irq = cur_res->start;
> +
> + /* Get EMAC I/O addresses */
> + ep->emac_reg_base = 0;
> + ep->ectl_reg_base = 0;
> + ep->emac_dsc_base = 0;
> + ep->mdio_reg_base = 0;
> +
> + cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> + "EMAC_REG_BASE");
> + if (cur_res)
> + ep->emac_reg_base = cur_res->start;
> +
> + cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> + "ECTL_REG_BASE");
> + if (cur_res)
> + ep->ectl_reg_base = cur_res->start;
> +
> + cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> + "EMAC_DSC_BASE");
> + if (cur_res)
> + ep->emac_dsc_base = cur_res->start
> + + ((IDX_TO_CHAN(emac_idx) * QUEUE_DESC_NUM) << 4);
> +
> +#ifdef EMAC_DO_INIT_MDIO
> + cur_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> + "MDIO_REG_BASE");
> + if (cur_res)
> + ep->mdio_reg_base = cur_res->start;
> +#endif
> +
> + if (!irq || !ep->emac_reg_base || !ep->ectl_reg_base || !ep->emac_dsc_base) {
> + printk(KERN_ERR "%s: Unable to get hardware resources\n",
> + netdev->name);
> + goto error;
> + }
> +
> + ep->mode_flags = config.flags;
> +
> + if (emac_check_shared_capability())
> + ep->slave = emac_shared;
> +
> + netdev->base_addr = ep->emac_reg_base;
> + netdev->dev_id = pdev->id;
> +
> +#ifdef EMAC_ARCH_HAS_MAC_ADDR
> + /* SoC or board hw has MAC address */
> + if (config.enetaddr[0] == 0 && config.enetaddr[1] == 0 &&
> + config.enetaddr[2] == 0 && config.enetaddr[3] == 0 &&
> + config.enetaddr[4] == 0 && config.enetaddr[5] == 0) {
> + if (!emac_arch_get_mac_addr(hw_emac_addr))
> + for (i = 0; i <= 5; i++)
> + config.enetaddr[i] = hw_emac_addr[i] & 0xff;
> + }
> +#endif
> + /* Setup the device */
> + res = emac_reset(netdev, GEMAC_RESET_COLD);
> + if (res) {
> + free_netdev(netdev);
> + goto error;
> + }
> +
> + /* driver system function */
> + ether_setup(netdev);
> +
> + /* Set generic Ethernet operations */
> + netdev->netdev_ops = &gemac_netdev_ops;
> + netdev->watchdog_timeo = TX_TIMEOUT;
> + netdev->ethtool_ops = &gemac_ethtool_ops;
> +
> + platform_set_drvdata(pdev, netdev);
> +
> + /* Register Ethernet device */
> + res = register_netdev(netdev);
> + if (res) {
> + printk(KERN_ERR "%s: Unable to register netdev\n",
> + netdev->name);
> + goto error;
> + }
> +
> + /* Setup transmit/receive buffers */
> + res = emac_setup_ring(ep);
> + if (res) {
> + printk(KERN_ERR "%s: Unable to allocate memory\n",
> + netdev->name);
> + goto error;
> + }
> +
> +#ifdef EMAC_TIMER_TICK_MDIO
> + /* Set EMAC timer */
> + init_timer(&emac_timer);
> + emac_timer.function = emac_timer_tick;
> + emac_timer.data = (unsigned long)netdev;
> + mod_timer(&emac_timer, jiffies + EMAC_TIMER_PERIOD);
> +#endif
> +
> + /* Install our interrupt handler(s) */
> +#ifdef EMAC_HAS_SEPARATE_RXTX_IRQS
> + if ((request_irq(irq, emac_rx_interrupt, _INTFLAG, "GEMAC RX", netdev) == 0) &&
> + (request_irq(irq + 1, emac_tx_interrupt, _INTFLAG, "GEMAC TX", netdev) == 0))
> + netdev->irq = irq;
> +#else
> + if (request_irq(irq, emac_interrupt, 0, "GEMAC", netdev) == 0)
> + netdev->irq = irq;
> +#endif
> +
> + printk(KERN_INFO "%s: EMAC(%d) driver version 2.1 IRQ=%d queue=%d %s",
> + netdev->name, pdev->id, netdev->irq, IDX_TO_CHAN(emac_idx),
> + emac_shared ? "shared\n" : "\n");
> +
> + printk(KERN_INFO "%s: MAC address=", netdev->name);
> + for (i = 0; i < 5; i++)
> + printk(KERN_CONT "%02x:", netdev->dev_addr[i]);
> +#ifdef CONFIG_SGMII
> + printk(KERN_CONT "%02x PHY=SGMII\n", netdev->dev_addr[i]);
> +#else
> + printk(KERN_CONT "%02x PHY=%s%sMII\n", netdev->dev_addr[i],
> + ((mdio_get_macsel() & DEVSTAT_MACSEL_RMII) ? "R" : ""),
> + ((mdio_get_macsel() & DEVSTAT_MACSEL_GMII) ? "G" : ""));
> +#endif
> + ++ndevs;
> + return 0;
> +
> + error:
> + free_netdev(netdev);
> + return res;
> +}
> +
> +static struct platform_driver emac_driver = {
> + .driver = {
> + .name = (char *) emac_driver_name,
> + .owner = THIS_MODULE,
> + },
> + .probe = emac_probe,
> +};
> +
> +static void __exit emac_cleanup(void)
> +{
> + platform_driver_unregister(&emac_driver);
> +}
> +module_exit(emac_cleanup);
> +
> +/*
> + * Initialize GEMAC controller
> + */
> +static int emac_init(void)
> +{
> + return platform_driver_register(&emac_driver);
> +}
> +
> +module_init(emac_init);
> +
> diff --git a/drivers/net/c6x_gmdio.c b/drivers/net/c6x_gmdio.c
> new file mode 100644
> index 0000000..6a82519
> --- /dev/null
> +++ b/drivers/net/c6x_gmdio.c
> @@ -0,0 +1,514 @@
> +/*
> + * Port on Texas Instruments TMS320C6x architecture
> + *
> + * Copyright (C) 2006, 2009, 2010 Texas Instruments Incorporated
> + * Author: Nicolas Videau ([email protected])
> + *
> + * This program is free software; you can redistribute it and/or modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + */
> +#include <linux/kernel.h>
> +#include <linux/sched.h>
> +#include <linux/delay.h>
> +#include <linux/init.h>
> +#include <linux/spinlock.h>
> +#include <linux/io.h>
> +
> +#include <asm/setup.h>
> +#include <asm/irq.h>
> +#include <asm/gmdio.h>
> +#include <asm/pll.h>
> +
> +static struct mdio_status mdios;
> +
> +/*
> + * Tick counts for timeout of each state
> + * Note that NWAYSTART falls through to NWAYWAIT which falls through
> + * to LINKWAIT. The timeout is not reset progressing from one state
> + * to the next, so the system has 5 seconds total to find a link.
> + */
> +static unsigned int phy_timeout[] = { 2, /* MDIO_PHY_MDIOINIT - min-delay */
> + 6, /* MDIO_PHY_RESET - .5 sec max */
> + 41, /* MDIO_PHY_NWAYSTART - 4 seconds */
> + 41, /* MDIO_PHY_NWAYWAIT - 4 seconds */
> + 51, /* MDIO_PHY_LINKWAIT - 5 seconds */
> + 0 };/* MDIO_PHY_LINKED - no timeout */
> +
> +static void mdio_init_state_machine(void)
> +{
> + mdios.phy_addr = 0;
> + mdios.phy_state = MDIO_PHY_MDIOINIT;
> + mdios.phy_ticks = 0;
> + mdios.link_status = MDIO_LINKSTATUS_NOLINK;
> +}
> +
> +/*
> + * Initialize the MDIO
> + */
> +int mdio_init(unsigned int txid_version)
> +{
> +#ifdef CONFIG_SOC_TMS320C6455
> + /* Get MAC interface */
> + mdios.macsel = (DSCR_DEVSTAT >> DEVSTAT_MACSEL_OFFSET) &
> + DEVSTAT_MACSEL_MASK;
> +#else
> + /* Default (no gigabit support) */
> + mdios.macsel = DEVSTAT_MACSEL_MII;
> +#endif
> +
> + /* Get Transmit identification and version */
> + mdios.emac_txidver = txid_version;
> +
> + mdios.mode = MDIO_MODE_AUTONEG; /* autonegotiate */
> + mdio_init_state_machine();
> + mdio_set_reg(MDIO_CONTROL, EMAC_B_ENABLE | (VBUSCLK & EMAC_M_CLKDIV));
> + return 0;
> +}
> +
> +/*
> + * Return the current MDIO/PHY status
> + */
> +unsigned int mdio_get_status(void)
> +{
> + return mdios.link_status;
> +}
> +
> +/*
> + * Return the current MDIO/PHY interface
> + */
> +unsigned int mdio_get_macsel(void)
> +{
> + mdios.macsel = (DSCR_DEVSTAT >> DEVSTAT_MACSEL_OFFSET) &
> + DEVSTAT_MACSEL_MASK;
> +
> + return mdios.macsel;
> +}
> +
> +/*
> + * Force a switch to the specified PHY, and start the negotiation process
> + */
> +static unsigned int mdio_init_phy_1(volatile unsigned int phy_addr)
> +{
> + unsigned short val, ack;
> + unsigned int lval;
> + unsigned int i;
> +
> + mdios.phy_addr = phy_addr;
> + mdios.link_status = MDIO_LINKSTATUS_NOLINK;
> +
> + /* Shutdown all other PHYs */
> + lval = mdio_get_reg(MDIO_ALIVE);
> + for (i = 0; lval; i++, lval >>= 1)
> + if ((lval & 1) && (i != phy_addr)) {
> + mdio_phy_write(MDIO_PHY_REG_CONTROL,
> + i,
> + (MDIO_PHY_B_ISOLATE |
> + MDIO_PHY_B_POWERDOWN));
> + mdio_phy_wait();
> + }
> +
> +#ifdef CONFIG_ARCH_BOARD_DSK6455
> + /* Settings for Broadcom phys */
> + if (mdios.macsel == DEVSTAT_MACSEL_RGMII) {
> + /* Put phy in copper mode */
> + mdio_phy_write(MDIO_PHY_REG_ACCESS, phy_addr,
> + MDIO_PHY_B_COPPER);
> + mdio_phy_wait_res_ack(val, ack);
> +
> + /* If the PHY did not ACK the write, return zero */
> + if (!ack)
> + return 0;
> +
> + mdio_phy_write(0x10, phy_addr, 0x0000);
> + mdio_phy_wait();
> +
> + /* Put phy in RGMII mode/in-band status data for PG 2.0 */
> + if (mdios.emac_txidver != 0x000C1207) {
> + mdio_phy_write(MDIO_PHY_REG_SHADOW, phy_addr,
> + MDIO_PHY_B_INBAND);
> + mdio_phy_wait_res_ack(val, ack);
> +
> + /* If the PHY did not ACK the write, return zero */
> + if (!ack)
> + return 0;
> + }
> +
> + /* Patch for (older) board revB with R822 soldered */
> + mdio_phy_write(MDIO_PHY_REG_ACCESS, phy_addr, 0x8C00);
> + mdio_phy_wait_res_ack(val, ack);
> + /* End of patch */
> + }
> +#endif
> +
> + if (mdios.macsel == DEVSTAT_MACSEL_GMII) {
> + /* Put phy in copper mode */
> + mdio_phy_write(MDIO_PHY_REG_ACCESS, phy_addr,
> + MDIO_PHY_B_COPPER);
> + mdio_phy_wait_res_ack(val, ack);
> +
> + /* If the PHY did not ACK the write, return zero */
> + if (!ack)
> + return 0;
> + }
> +
> + /* Ready for next init step */
> + mdios.phy_state = MDIO_PHY_RESET;
> + mdios.phy_ticks = 0;
> +
> + return 1;
> +}
> +
> +static unsigned int mdio_init_phy_2(volatile unsigned int phy_addr)
> +{
> + unsigned short val, val2, valgig = 0;
> +
> + mdios.phy_addr = phy_addr;
> +
> + /* Read the STATUS reg to check autonegotiation capability */
> + mdio_phy_read(MDIO_PHY_REG_STATUS, phy_addr);
> + mdio_phy_wait_res(val);
> +
> + if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
> + (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
> + mdio_phy_read(MDIO_PHY_REG_EXTSTATUS, phy_addr);
> + mdio_phy_wait_res(valgig);
> + }
> +
> + /* See if we auto-neg or not */
> + if ((mdios.mode & MDIO_MODE_AUTONEG) &&
> + (val & MDIO_PHY_B_AUTOCAPABLE)) {
> + /* We will use NWAY */
> +
> + /* Advertise 1000 for supported interfaces */
> + if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
> + (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
> + valgig >>= 4;
> + valgig &= MDIO_PHY_ADV_FD1000;
> +
> + mdio_phy_write(MDIO_PHY_REG_1000CONTROL, phy_addr,
> + valgig);
> + mdio_phy_wait();
> + }
> +
> + /* Shift down the capability bits */
> + val >>= 6;
> +
> + /* Mask with the capabilities */
> + val &= (MDIO_PHY_B_AFD100 | MDIO_PHY_B_AHD100 |
> + MDIO_PHY_B_AFD10 | MDIO_PHY_B_AHD10);
> +
> + /* Set Ethernet message bit */
> + val |= MDIO_PHY_B_MSG;
> +
> + /* Write out advertisement */
> + mdio_phy_write(MDIO_PHY_REG_ADVERTISE, phy_addr, val);
> + mdio_phy_wait();
> +
> + /* Start NWAY */
> + mdio_phy_write(MDIO_PHY_REG_CONTROL,
> + phy_addr,
> + MDIO_PHY_B_AUTONEGEN);
> + mdio_phy_wait();
> +
> + mdio_phy_write(MDIO_PHY_REG_CONTROL,
> + phy_addr,
> + (MDIO_PHY_B_AUTONEGEN | MDIO_PHY_B_AUTORESTART));
> + mdio_phy_wait();
> +
> + /* Setup current state */
> + mdios.mode |= MDIO_MODE_NWAYACTIVE;
> + mdios.phy_state = MDIO_PHY_NWAYSTART;
> + mdios.phy_ticks = 0;
> +
> + } else {
> + /* Otherwise use a fixed configuration */
> +
> + /* Shift down the capability bits */
> + val >>= 10;
> +
> + /* Mask with possible modes */
> + val &= (MDIO_MODE_HD10 | MDIO_MODE_FD10 |
> + MDIO_MODE_HD100 | MDIO_MODE_FD100);
> +
> + if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
> + (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
> + valgig >>= 8;
> + valgig &= MDIO_MODE_FD1000;
> +
> + valgig &= mdios.mode;
> + }
> +
> + /* Mask with what the User wants to allow */
> + val &= mdios.mode;
> +
> + /* If nothing if left, move on */
> + if ((!val) && (!valgig))
> + return 0;
> +
> + /* Setup Control word and pending status */
> + if (valgig) {
> + val2 = MDIO_PHY_B_SPEEDMSB | MDIO_PHY_B_DUPLEXFULL;
> + mdios.pending_status = MDIO_LINKSTATUS_FD1000;
> + } else if (val & MDIO_MODE_FD100) {
> + val2 = MDIO_PHY_B_SPEEDLSB | MDIO_PHY_B_DUPLEXFULL;
> + mdios.pending_status = MDIO_LINKSTATUS_FD100;
> + } else if (val & MDIO_MODE_HD100) {
> + val2 = MDIO_PHY_B_SPEEDLSB;
> + mdios.pending_status = MDIO_LINKSTATUS_HD100;
> + } else if (val & MDIO_MODE_FD10) {
> + val2 = MDIO_PHY_B_DUPLEXFULL;
> + mdios.pending_status = MDIO_PHY_B_FD10;
> + } else {
> + val2 = 0;
> + mdios.pending_status = MDIO_LINKSTATUS_HD10;
> + }
> +
> + /* Add in loopback if user wanted it */
> + if (mdios.mode & MDIO_MODE_LOOPBACK)
> + val2 |= MDIO_PHY_B_LOOPBACK;
> +
> + /* Configure PHY */
> + mdio_phy_write(MDIO_PHY_REG_CONTROL, phy_addr,
> + (val2 | MDIO_PHY_B_AUTORESTART));
> + mdio_phy_wait();
> +
> + /* Add in external loopback with plug if user wanted it */
> + if (mdios.mode & MDIO_MODE_EXTLOOPBACK) {
> + mdio_phy_write(MDIO_PHY_REG_SHADOW, phy_addr,
> + MDIO_PHY_B_EXTLOOPBACK);
> + mdio_phy_wait();
> + }
> +
> + /* Setup current state */
> + mdios.mode &= ~MDIO_MODE_NWAYACTIVE;
> + mdios.phy_state = MDIO_PHY_LINKWAIT;
> + mdios.phy_ticks = 0;
> + }
> + return 1;
> +}
> +
> +
> +/*
> + * Called each 100mS to check if MDIO status has changed.
> + * A MDIO event is returned.
> + */
> +unsigned int mdio_timer_tick(void)
> +{
> + unsigned int res = MDIO_EVENT_NOCHANGE;
> + unsigned short val, val2, valgig = 0, valgig2 = 0, ack;
> + unsigned int lval;
> +
> + if (mdios.phy_state == MDIO_PHY_LINKED) {
> + /*
> + * Check for a "link-change" status indication or a link
> + * down indication.
> + */
> + lval = mdio_get_reg(MDIO_LINKINTRAW) & 1;
> + mdio_set_reg(MDIO_LINKINTRAW, lval);
> + if (lval || !(mdio_get_reg(MDIO_LINK) & (1 << mdios.phy_addr))) {
> +
> + mdios.link_status = MDIO_LINKSTATUS_NOLINK;
> + mdios.phy_ticks = 0;
> + res = MDIO_EVENT_LINKDOWN;
> +
> + /* If not NWAY, just wait for link */
> + if (!(mdios.mode & MDIO_MODE_NWAYACTIVE))
> + mdios.phy_state = MDIO_PHY_LINKWAIT;
> + else {
> + /* Handle NWAY condition */
> + mdio_phy_read(MDIO_PHY_REG_STATUS,
> + mdios.phy_addr);
> + mdio_phy_wait();
> + mdio_phy_read(MDIO_PHY_REG_STATUS,
> + mdios.phy_addr);
> + mdio_phy_wait_res_ack(val, ack);
> + if (!ack)
> + mdio_init_state_machine();
> +
> + else if (!(val & MDIO_PHY_B_LINKSTATUS)) {
> + /* No Link - restart NWAY */
> + mdios.phy_state = MDIO_PHY_NWAYSTART;
> +
> + mdio_phy_write(MDIO_PHY_REG_CONTROL,
> + mdios.phy_addr,
> + (MDIO_PHY_B_AUTONEGEN |
> + MDIO_PHY_B_AUTORESTART));
> + mdio_phy_wait();
> + } else
> + /* We have a Link - re-read NWAY params */
> + mdios.phy_state = MDIO_PHY_NWAYWAIT;
> + }
> + }
> + }
> +
> + if (mdios.phy_state != MDIO_PHY_LINKED) {
> + /* Bump the time counter */
> + mdios.phy_ticks++;
> +
> + /* Process differently based on state */
> + switch (mdios.phy_state) {
> +#if !(defined(CONFIG_SOC_TMS3206472) || defined(CONFIG_SOC_TMS3206474)) && \
> + !defined(CONFIG_SOC_TMS3206457)
> + case MDIO_PHY_RESET:
> + /* Don't read reset status for the first 100 to 200 ms */
> + if (mdios.phy_ticks < 2)
> + break;
> +
> + /* See if the PHY has come out of reset */
> + mdio_phy_read(MDIO_PHY_REG_CONTROL,
> + mdios.phy_addr);
> + mdio_phy_wait_res_ack(val, ack);
> +
> + if (ack && !(val & MDIO_PHY_B_RESET)) {
> + /* PHY is not reset.
> + * If the PHY init is going well, break out */
> + if (mdio_init_phy_2(mdios.phy_addr))
> + break;
> + /* Else, this PHY is toast.
> + * Manually trigger a timeout */
> + mdios.phy_ticks = phy_timeout[mdios.phy_state];
> + }
> +
> + /* Fall through to timeout check */
> +#endif
> + case MDIO_PHY_MDIOINIT:
> + check_timeout:
> + /* Here we just check timeout and try to find a PHY */
> + if (mdios.phy_ticks >= phy_timeout[mdios.phy_state]) {
> + /* Try the next PHY if anything but
> + * a MDIOINIT condition */
> + if (mdios.phy_state != MDIO_PHY_MDIOINIT)
> + if (++mdios.phy_addr == 32)
> + mdios.phy_addr = 0;
> +
> + lval = mdio_get_reg(MDIO_ALIVE);
> +
> + for (val = 0; val < 32; val++) {
> +
> + if ((lval & (1 << mdios.phy_addr)) &&
> + (mdio_init_phy_1(mdios.phy_addr)))
> + break;
> +
> + if (++mdios.phy_addr == 32)
> + mdios.phy_addr = 0;
> + }
> +
> + /* If we didn't find a PHY, try again */
> + if (val == 32) {
> + mdios.phy_addr = 0;
> + mdios.phy_state = MDIO_PHY_MDIOINIT;
> + mdios.phy_ticks = 0;
> + res = MDIO_EVENT_PHYERROR;
> + }
> + }
> + break;
> +
> + case MDIO_PHY_NWAYSTART:
> + /* Start NWAY */
> +
> + /* Read the CONTROL reg to verify "restart" is not set */
> + mdio_phy_read(MDIO_PHY_REG_CONTROL, mdios.phy_addr);
> + mdio_phy_wait_res_ack(val, ack);
> + if (!ack) {
> + mdio_init_state_machine();
> + break;
> + }
> +
> + if (val & MDIO_PHY_B_AUTORESTART)
> + goto check_timeout;
> +
> + /* Flush latched "link status" from the STATUS reg */
> + mdio_phy_read(MDIO_PHY_REG_STATUS, mdios.phy_addr);
> + mdio_phy_wait();
> +
> + mdios.phy_state = MDIO_PHY_NWAYWAIT;
> +
> + /* Fallthrough */
> +
> + case MDIO_PHY_NWAYWAIT:
> + /* Waiting NWAY to complete */
> +
> + /* Read the STATUS reg to check for "complete" */
> + mdio_phy_read(MDIO_PHY_REG_STATUS, mdios.phy_addr);
> + mdio_phy_wait_res_ack(val, ack);
> + if (!ack) {
> + mdio_init_state_machine();
> + break;
> + }
> +
> + if (!(val & MDIO_PHY_B_AUTOCOMPLETE))
> + goto check_timeout;
> +#if !(defined(CONFIG_SOC_TMS3206472) || defined(CONFIG_SOC_TMS3206474)) && !defined(CONFIG_SOC_TMS3206457)
> + /* We can now check the negotiation results */
> + if ((mdios.macsel == DEVSTAT_MACSEL_GMII) ||
> + (mdios.macsel == DEVSTAT_MACSEL_RGMII)) {
> + mdio_phy_read(MDIO_PHY_REG_1000CONTROL,
> + mdios.phy_addr);
> + mdio_phy_wait_res(valgig);
> + mdio_phy_read(MDIO_PHY_REG_1000STATUS,
> + mdios.phy_addr);
> + mdio_phy_wait_res(valgig2);
> + }
> +#endif
> + mdio_phy_read(MDIO_PHY_REG_ADVERTISE, mdios.phy_addr);
> + mdio_phy_wait_res(val);
> + mdio_phy_read(MDIO_PHY_REG_PARTNER, mdios.phy_addr);
> + mdio_phy_wait_res(val2);
> +
> + val2 &= val;
> +#if !(defined(CONFIG_SOC_TMS3206472) || defined(CONFIG_SOC_TMS3206474)) && !defined(CONFIG_SOC_TMS3206457)
> + if ((valgig & MDIO_PHY_ADV_FD1000) &&
> + (valgig2 & MDIO_PHY_PRT_FD1000))
> + mdios.pending_status = MDIO_LINKSTATUS_FD1000;
> + else if (val2 & MDIO_PHY_B_AFD100)
> + mdios.pending_status = MDIO_LINKSTATUS_FD100;
> +#else
> + if (val2 & MDIO_PHY_B_AFD100)
> + mdios.pending_status = MDIO_LINKSTATUS_FD100;
> +#endif
> + else if (val2 & MDIO_PHY_B_AHD100)
> + mdios.pending_status = MDIO_LINKSTATUS_HD100;
> + else if (val2 & MDIO_PHY_B_AFD10)
> + mdios.pending_status = MDIO_LINKSTATUS_FD10;
> + else if (val2 & MDIO_PHY_B_AHD10)
> + mdios.pending_status = MDIO_LINKSTATUS_HD10;
> + else if (val & MDIO_PHY_B_AHD100)
> + mdios.pending_status = MDIO_LINKSTATUS_HD100;
> + else
> + mdios.pending_status = MDIO_LINKSTATUS_HD10;
> +
> + mdios.phy_state = MDIO_PHY_LINKWAIT;
> +
> + case MDIO_PHY_LINKWAIT:
> + /* Waiting for LINK */
> + mdio_phy_read(MDIO_PHY_REG_STATUS, mdios.phy_addr);
> + mdio_phy_wait_res_ack(val, ack);
> + if (!ack) {
> + mdio_init_state_machine();
> + break;
> + }
> +
> + if (!(val & MDIO_PHY_B_LINKSTATUS))
> + goto check_timeout;
> +
> + /* Make sure we're linked in the MDIO module as well */
> + lval = mdio_get_reg(MDIO_LINK);
> + if (!(lval & (1 << mdios.phy_addr)))
> + goto check_timeout;
> +
> + /* Start monitoring this PHY */
> + mdio_set_reg(MDIO_USERPHYSEL0, mdios.phy_addr);
> +
> + /* Clear the link change flag so we can detect a "re-link" later */
> + mdio_set_reg(MDIO_LINKINTRAW, 1);
> +
> + /* Setup our linked state */
> + mdios.phy_state = MDIO_PHY_LINKED;
> + mdios.link_status = mdios.pending_status;
> + res = MDIO_EVENT_LINKUP;
> + break;
> + }
> + }
> + return res;
> +}


2011-05-12 00:57:56

by Mark Salter

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Wed, 2011-05-11 at 14:34 -0700, Randy Dunlap wrote:
> Please run the patches thru checkpatch.pl. You don't have to fix
> everything that it whines about, just use good judgment.

Thanks Randy.

Was there anything particular that jumped out at you. I did run
checkpatch and there were 7 seven errors but none seemed fixable to
me (unless there really is a way to get rid of kernel_thread). The
warnings were almost all about exceeded 80 char line width. I have
been working on those for a while and there's a lot less than there
used to be! :-)

--Mark

2011-05-12 01:07:16

by Randy Dunlap

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Wed, 11 May 2011 20:57:53 -0400 Mark Salter wrote:

> On Wed, 2011-05-11 at 14:34 -0700, Randy Dunlap wrote:
> > Please run the patches thru checkpatch.pl. You don't have to fix
> > everything that it whines about, just use good judgment.
>
> Thanks Randy.
>
> Was there anything particular that jumped out at you. I did run
> checkpatch and there were 7 seven errors but none seemed fixable to
> me (unless there really is a way to get rid of kernel_thread). The
> warnings were almost all about exceeded 80 char line width. I have
> been working on those for a while and there's a lot less than there
> used to be! :-)

There was one in drivers/platform/c6x/ where a driver included asm/timer.h
instead of linux/timer.h (IIRC - I don't have the patch handy ATM to run it
again). checkpatch said to use linux/ instead of asm/.

---
~Randy
*** Remember to use Documentation/SubmitChecklist when testing your code ***

2011-05-12 01:16:33

by Mark Salter

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Wed, 2011-05-11 at 18:07 -0700, Randy Dunlap wrote:
> There was one in drivers/platform/c6x/ where a driver included asm/timer.h
> instead of linux/timer.h (IIRC - I don't have the patch handy ATM to run it
> again). checkpatch said to use linux/ instead of asm/.

Ah, okay. Yeah, that's in a few places actually. Generally speaking,
there is no asm/timer.h and linux/timer.h doesn't include it. Maybe I
should just rename it or make it mach/timer.h which is probably more
appropriate anyway.

--Mark

2011-05-12 02:42:04

by Milton Miller

[permalink] [raw]
Subject: Re: [04/16] add support for C64x+ debugger based console

On Wed, 11 May 2011 about 20:13:51 -0000, Mark Salter wrote:
> Texas Instruments debugger support for the C64X+ family of DSPs includes a
> console for the unit under test. This patch adds write-only console support
> to send kernel output to the debugger. It is safe to have this driver in
> place even if the system is not being run under the debugger.
>
> Signed-off-by: Mark Salter <[email protected]>
>
> ---
> drivers/tty/hvc/Makefile | 1 +
> drivers/tty/hvc/hvc_c6x.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 126 insertions(+), 0 deletions(-)
> create mode 100644 drivers/tty/hvc/hvc_c6x.c


Hmm, no Kconfig? Oh, I see, you have a very minimal entry in
arch/c6x/Kconfig via "[07/16] C6X: add toplevel configury and makefile".

Except that is too minimal. It should give the user guidance
like the changelog: it provides a hook for a that the debuger
can set a breakpoint to know when to pick up the data, is safe
when the debugger is not enabled, etc. Answer "why would a
user want this?".

Also, I prefer it to be local with the driver and makefile even
if it depends on your architecture. There is nothing processor
architeture specific about this driver, even the asm is 2 nops
and a label; so some other arch may want to reuse this driver.

> +/*
> + * TI C6X Host Port hypervisor console
> + */

Nothing is really hypervisor, other than the name of the framework.
More like debugger driver?

> +
> +#include <linux/console.h>
> +#include <linux/delay.h>

Not sure you use anything from delay.h

> +#include <linux/err.h>
> +#include <linux/init.h>
> +#include <linux/moduleparam.h>
> +#include <linux/types.h>
> +
> +#include "hvc_console.h"
> +
> +#define PARAMSIZE 8
> +#define MSGSIZE 256
> +
> +#define CIO_READ 0xF2
> +#define CIO_WRITE 0xF3
> +
> +#define CIO_STDIN 0
> +#define CIO_STDOUT 1
> +#define CIO_STDERR 2
> +

So you probably have some method to read characters that could be added.
No pressure, but that could be useful. Your raw transport also has
multiple channels which could be used.

> +struct c6x_msg {
> + unsigned int length;
> + unsigned char command;
> + unsigned char params[PARAMSIZE];
> + unsigned char msg[MSGSIZE];
> +};
> +
> +union c6x_msgparam {
> + unsigned char params[PARAMSIZE];
> + struct {
> + unsigned short fd;
> + unsigned short count;
> + } host_write;
> +};
> +
> +/*
> + * __CIOBUF__ and C$$IO$$ are special symbols for debugger.
> + *
> + * If debugger is running kernel, it will set a breakpoint
> + * at C$$IO$$ which is hit when the kernel wants attention
> + * from the debugger. __CIOBUF__ is used to pass messages
> + * between debugger and kernel when the breakpoint is hit.
> + */
> +struct c6x_msg _CIOBUF_;
> +
> +static noinline void notify_debugger(void)
> +{
> + asm volatile (".global C$$IO$$\n"
> + "nop\n"
> + "C$$IO$$: nop\n");
> +}
> +
> +static int hvc_c6x_put_chars(uint32_t vt, const char *buf, int count)
> +{
> + union c6x_msgparam params;
> + int to_write, remaining;
> +
> + remaining = count;
> + while (remaining > 0) {
> + to_write = (remaining > MSGSIZE) ? MSGSIZE : remaining;
> +
> + _CIOBUF_.length = to_write;
> + _CIOBUF_.command = CIO_WRITE;
> +
> + params.host_write.fd = cpu_to_le16(CIO_STDOUT);
> + params.host_write.count = cpu_to_le16(to_write);
> + memcpy(_CIOBUF_.params, &params, PARAMSIZE);
> +
> + memcpy(_CIOBUF_.msg, buf, to_write);
> +
> + notify_debugger();
> +
> + remaining -= to_write;
> + }
> + return count;
> +}
> +
> +#ifdef CONFIG_EARLY_PRINTK
> +void hvc_c6x_early_puts(const char *buf, unsigned count)
> +{
> + hvc_c6x_put_chars(0, buf, count);
> +}
> +#endif

Hmm, so you have

(1) early_printk only avail if CONFIG_EARLY_PRINTK (no #else nop),
and this hook is protyped in include/early_printk under ifdef.

(2) arch/c6x/kernel/early_console.c implements a hook, with an
explict ifdef for this driver to fill in the hook

So both files ifdef the config used to build the other file.

Do you have other hook implementations for your early_puts?

(3) the effect of doing the above gets a console that gets called
with upto 512 characters per buffer (which would require 2 messages,
but you handle that), instead of the hvc_console N_OUTBUF = 16
per loop.


The hvc console is supposed to auto-register the console either when
the hvc_console console_initcall is made or when some sub driver calls
hvc_instantiate. While its not as clear as it used to be that calling
it early is safe, I think it stll is.

I can see how the early-printk console could be about 16x faster;
maybe we should create a static buffer for console output. Its
always filled under the console locks and drained under the same
call. (The n_outbuf code was added to hvc later). Some drivers
need the aligned to long of that buffer and we dont' want to
grow the stack too much. ... but I digress. I won't hold
the driver up for that, but could you take a look?

> +
> +static int hvc_c6x_get_chars(uint32_t vt, char *buf, int count)
> +{
> + return 0;
> +}
> +
> +static const struct hv_ops hvc_c6x_get_put_ops = {
> + .get_chars = hvc_c6x_get_chars,
> + .put_chars = hvc_c6x_put_chars,
> +};
> +
> +static int __init hvc_c6x_console_init(void)
> +{
> + hvc_instantiate(0, 0, &hvc_c6x_get_put_ops);
> + add_preferred_console("hvc", 0, NULL);

This (calling add_preferred_console from the drivers console_initcall)
is bad if you ever get an alternative console. It seems convinient
until then.

> + return 0;
> +}
> +console_initcall(hvc_c6x_console_init);
> +
> +static int __init hvc_c6x_init(void)
> +{
> + struct hvc_struct *s;
> + s = hvc_alloc(0, 0, &hvc_c6x_get_put_ops, 128);

So you tell the hvc layer you want upto 128 bytes at a time, but
your driver can handle MSGSIZE = 256 ? Why would you not request
MSGSIZE at a time?


> + return IS_ERR(s) ? PTR_ERR(s) : 0;
> +}
> +device_initcall(hvc_c6x_init);

milton

2011-05-12 12:34:27

by Mark Salter

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Wed, 2011-05-11 at 20:13 +0000, Milton Miller wrote:
> On Wed, 11 May 2011 around 17:11:19 EST, Mark Salter wrote:
> > This patch series adds support for a new architecture (arch/c6x) to
> > Linux. This architecture supports members of the Texas Instruments
> > family of C64x single and multicore DSPs. The multicore DSPs do not
> > support cache coherancy, so are not suitable for SMP. Also, these are
> > no-mmu processors. This core architecture is VLIW with an instruction
> > set optimized for DSP applications. For details on the processors:
>
> So all the changelogs talk about C64x but the arch and all the configs
> are called c6x? Is it that hard to type 2 digits? Or do you expect
> an additional chip that breaks the C64 but would fit the C6x name?
>

The full DSP family is C6000. The current port supports C64xx processors
within that family. There are also C67xx processors with floating point
support. Future support for those seem likely as the instruction set is
nearly identical.

> Also, a couple of one liners while preparing my comments on hvc_c6x:
>
> [09/16] C6X: add kernel files
>
> in kernel/setup.c you include linux/delay.h multiple times
>
Okay, I'll get rid of it.

>
>
> [11/16] C6X: add lib files
>
> arch/c6x/lib/memset.c
>
> (1) file header says linux/arch/c6x/lib/memcmp.c
> (you should probably just delete such headers, they are just maintence errors)

Agreed. I've been removing these as I find them. I need to sweep the
whole code base and get rid of them all.

>
> (2) it appears to mach lib/string.c implementation except (1) register (2)
> uses post-increment instead of pre-increment. Does it matter with gcc?
>
> arch/c6x/lib/memcmp.c
> your version returns -1 or 1 while string.c returns the difference
> after promotion to int. man page for userspace says just integer less
> than or greater, so I guess this is ok. But is this more efficient,
> or could you use the generic version?

I'm pretty sure the generic versions would be just fine using gcc. There
may have been a reason for them when using the TI toolchain, but it
makes sense to just ditch the c6x versions at this point.

--Mark


2011-05-12 12:55:56

by Mark Salter

[permalink] [raw]
Subject: Re: [04/16] add support for C64x+ debugger based console

On Wed, 2011-05-11 at 21:41 -0500, Milton Miller wrote:
> On Wed, 11 May 2011 about 20:13:51 -0000, Mark Salter wrote:
> > Texas Instruments debugger support for the C64X+ family of DSPs includes a
> > console for the unit under test. This patch adds write-only console support
> > to send kernel output to the debugger. It is safe to have this driver in
> > place even if the system is not being run under the debugger.
> >
> > Signed-off-by: Mark Salter <[email protected]>
> >
> > ---
> > drivers/tty/hvc/Makefile | 1 +
> > drivers/tty/hvc/hvc_c6x.c | 125 +++++++++++++++++++++++++++++++++++++++++++++
> > 2 files changed, 126 insertions(+), 0 deletions(-)
> > create mode 100644 drivers/tty/hvc/hvc_c6x.c
>
>
> Hmm, no Kconfig? Oh, I see, you have a very minimal entry in
> arch/c6x/Kconfig via "[07/16] C6X: add toplevel configury and makefile".
>
> Except that is too minimal. It should give the user guidance
> like the changelog: it provides a hook for a that the debuger
> can set a breakpoint to know when to pick up the data, is safe
> when the debugger is not enabled, etc. Answer "why would a
> user want this?".
>
> Also, I prefer it to be local with the driver and makefile even
> if it depends on your architecture. There is nothing processor
> architeture specific about this driver, even the asm is 2 nops
> and a label; so some other arch may want to reuse this driver.
>
> > +/*
> > + * TI C6X Host Port hypervisor console
> > + */
>
> Nothing is really hypervisor, other than the name of the framework.
> More like debugger driver?
>
> > +
> > +#include <linux/console.h>
> > +#include <linux/delay.h>
>
> Not sure you use anything from delay.h
>
> > +#include <linux/err.h>
> > +#include <linux/init.h>
> > +#include <linux/moduleparam.h>
> > +#include <linux/types.h>
> > +
> > +#include "hvc_console.h"
> > +
> > +#define PARAMSIZE 8
> > +#define MSGSIZE 256
> > +
> > +#define CIO_READ 0xF2
> > +#define CIO_WRITE 0xF3
> > +
> > +#define CIO_STDIN 0
> > +#define CIO_STDOUT 1
> > +#define CIO_STDERR 2
> > +
>
> So you probably have some method to read characters that could be added.
> No pressure, but that could be useful. Your raw transport also has
> multiple channels which could be used.
>
> > +struct c6x_msg {
> > + unsigned int length;
> > + unsigned char command;
> > + unsigned char params[PARAMSIZE];
> > + unsigned char msg[MSGSIZE];
> > +};
> > +
> > +union c6x_msgparam {
> > + unsigned char params[PARAMSIZE];
> > + struct {
> > + unsigned short fd;
> > + unsigned short count;
> > + } host_write;
> > +};
> > +
> > +/*
> > + * __CIOBUF__ and C$$IO$$ are special symbols for debugger.
> > + *
> > + * If debugger is running kernel, it will set a breakpoint
> > + * at C$$IO$$ which is hit when the kernel wants attention
> > + * from the debugger. __CIOBUF__ is used to pass messages
> > + * between debugger and kernel when the breakpoint is hit.
> > + */
> > +struct c6x_msg _CIOBUF_;
> > +
> > +static noinline void notify_debugger(void)
> > +{
> > + asm volatile (".global C$$IO$$\n"
> > + "nop\n"
> > + "C$$IO$$: nop\n");
> > +}
> > +
> > +static int hvc_c6x_put_chars(uint32_t vt, const char *buf, int count)
> > +{
> > + union c6x_msgparam params;
> > + int to_write, remaining;
> > +
> > + remaining = count;
> > + while (remaining > 0) {
> > + to_write = (remaining > MSGSIZE) ? MSGSIZE : remaining;
> > +
> > + _CIOBUF_.length = to_write;
> > + _CIOBUF_.command = CIO_WRITE;
> > +
> > + params.host_write.fd = cpu_to_le16(CIO_STDOUT);
> > + params.host_write.count = cpu_to_le16(to_write);
> > + memcpy(_CIOBUF_.params, &params, PARAMSIZE);
> > +
> > + memcpy(_CIOBUF_.msg, buf, to_write);
> > +
> > + notify_debugger();
> > +
> > + remaining -= to_write;
> > + }
> > + return count;
> > +}
> > +
> > +#ifdef CONFIG_EARLY_PRINTK
> > +void hvc_c6x_early_puts(const char *buf, unsigned count)
> > +{
> > + hvc_c6x_put_chars(0, buf, count);
> > +}
> > +#endif
>
> Hmm, so you have
>
> (1) early_printk only avail if CONFIG_EARLY_PRINTK (no #else nop),
> and this hook is protyped in include/early_printk under ifdef.
>
> (2) arch/c6x/kernel/early_console.c implements a hook, with an
> explict ifdef for this driver to fill in the hook
>
> So both files ifdef the config used to build the other file.
>
> Do you have other hook implementations for your early_puts?

No. None of the currently supported boards have a simple UART :(
Several of the boards do have i2c-uart bridges but we don't have
code to support those outside of the normal i2c driver which is
too late for early_printk.

>
> (3) the effect of doing the above gets a console that gets called
> with upto 512 characters per buffer (which would require 2 messages,
> but you handle that), instead of the hvc_console N_OUTBUF = 16
> per loop.
>
>
> The hvc console is supposed to auto-register the console either when
> the hvc_console console_initcall is made or when some sub driver calls
> hvc_instantiate. While its not as clear as it used to be that calling
> it early is safe, I think it stll is.
>
> I can see how the early-printk console could be about 16x faster;
> maybe we should create a static buffer for console output. Its
> always filled under the console locks and drained under the same
> call. (The n_outbuf code was added to hvc later). Some drivers
> need the aligned to long of that buffer and we dont' want to
> grow the stack too much. ... but I digress. I won't hold
> the driver up for that, but could you take a look?

Yes I will. This debugger console support was originally done using
the tty interface directly but it was suggested to use the HVC
framework to simplify it (which it did). But we did notice it seemed
somewhat slower than the direct tty driver, so this could use some
investigation.

>
> > +
> > +static int hvc_c6x_get_chars(uint32_t vt, char *buf, int count)
> > +{
> > + return 0;
> > +}
> > +
> > +static const struct hv_ops hvc_c6x_get_put_ops = {
> > + .get_chars = hvc_c6x_get_chars,
> > + .put_chars = hvc_c6x_put_chars,
> > +};
> > +
> > +static int __init hvc_c6x_console_init(void)
> > +{
> > + hvc_instantiate(0, 0, &hvc_c6x_get_put_ops);
> > + add_preferred_console("hvc", 0, NULL);
>
> This (calling add_preferred_console from the drivers console_initcall)
> is bad if you ever get an alternative console. It seems convinient
> until then.
>
> > + return 0;
> > +}
> > +console_initcall(hvc_c6x_console_init);
> > +
> > +static int __init hvc_c6x_init(void)
> > +{
> > + struct hvc_struct *s;
> > + s = hvc_alloc(0, 0, &hvc_c6x_get_put_ops, 128);
>
> So you tell the hvc layer you want upto 128 bytes at a time, but
> your driver can handle MSGSIZE = 256 ? Why would you not request
> MSGSIZE at a time?
>

We should. I just copied the above from hvc_tile.c without giving the
128 a lot of thought.

Thanks for the great guidance. I'll rework the patch with above comments
in mind.

--Mark

2011-05-13 13:55:20

by Pavel Machek

[permalink] [raw]
Subject: Re: [PATCH 01/16] fix default __strnlen_user macro

Hi!

> The existing __strnlen_user macro simply resolved to strnlen. However, the
> count returned by strnlen_user should include the NULL byte. This patch
> fixes the __strnlen_user macro to include the NULL byte in the count.

Are you sure? Having strnlen and _foo_strnlen with different return
values seems very very dangerous.

> @@ -289,7 +289,7 @@ strncpy_from_user(char *dst, const char __user *src, long count)
> * Return 0 on exception, a value greater than N if too long
> */
> #ifndef __strnlen_user
> -#define __strnlen_user strnlen
> +#define __strnlen_user(s, n) (strnlen((s), (n)) + 1)
> #endif
>

--
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

2011-05-13 14:41:03

by Mark Salter

[permalink] [raw]
Subject: Re: [PATCH 01/16] fix default __strnlen_user macro

On Fri, 2011-05-13 at 13:55 +0000, Pavel Machek wrote:
> > The existing __strnlen_user macro simply resolved to strnlen. However, the
> > count returned by strnlen_user should include the NULL byte. This patch
> > fixes the __strnlen_user macro to include the NULL byte in the count.
>
> Are you sure? Having strnlen and _foo_strnlen with different return
> values seems very very dangerous.
>

Yes. I am sure based on comments and usage elsewhere in the kernel.
That difference certainly through me off track as I tried to figure out
why my kernels failed to mount roots when I switched to the generic
uaccess.h.

--Mark

2011-05-13 15:30:23

by Ben Hutchings

[permalink] [raw]
Subject: Re: [PATCH 03/16] add driver for C64x+ ethernet driver

Please send network drivers to netdev for review.

I haven't looked at this thoroughly, but I noticed a few things:

On Wed, 2011-05-11 at 16:13 -0400, Mark Salter wrote:
> From: Aurelien Jacquiot <[email protected]>
>
> This patch adds a network driver to support the ethernet interface found on
> several Texas Instruments C64X+ based System on Chips. In particular, this
> driver has been tested on the TMS320C6455, TMS320C6457, TMS320C6472, and
> TMS320C6474 parts.
[...]
> --- /dev/null
> +++ b/drivers/net/c6x_gemac.c
[...]
> +static int __init get_mac_addr_from_cmdline(char *str)
> +{
> + const char *start = (const char *) str;
> + const char *end;
> + int count;
> +
> + for (count = 0; count < 6; count++) {
> + config.enetaddr[count] = _hex_strtoul(start, &end);
> + if (end == start)
> + return 0;
> + if ((*end != ':') && (count != 5))
> + return 0;
> + start = end + 1;
> + }
> + return 1;
> +}
> +
> +__setup("emac_addr=", get_mac_addr_from_cmdline);
> +
> +static int __init set_emac_shared(char *str)
> +{
> + emac_shared = 1;
> + return 1;
> +}
> +
> +__setup("emac_shared", set_emac_shared);

These parameters should be provided by platform data.

> +/*
> + * Get the device statistic
> + */
> +static struct net_device_stats *emac_get_stats(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + unsigned int reg;
> + unsigned int dummy;
> + int i;
> +
> + emac_set_stat(dev->stats.multicast, EMAC_RXMCASTFRAMES);
> + emac_set_stat(dev->stats.collisions, EMAC_TXCOLLISION);
> + emac_set_stat(dev->stats.rx_length_errors, EMAC_RXOVERSIZED);
> + emac_set_stat(dev->stats.rx_length_errors, EMAC_RXUNDERSIZED);
> + emac_set_stat(dev->stats.rx_crc_errors, EMAC_RXCRCERRORS);
> + emac_set_stat(dev->stats.rx_frame_errors, EMAC_RXALIGNCODEERRORS);
> + emac_set_stat(dev->stats.tx_carrier_errors, EMAC_TXCARRIERSLOSS);
> + emac_set_stat(dev->stats.tx_fifo_errors, EMAC_TXUNDERRUN);
> + emac_set_stat(dev->stats.tx_window_errors, EMAC_TXLATECOLL);
> +
> + /* ACK statistic by write-to-decrement */
> + reg = EMAC_RXGOODFRAMES;
> + for (i = 0; i < EMAC_NUM_STATREGS; i++) {
> + dummy = emac_get_reg(reg);
> + emac_set_reg(reg, dummy);
> + reg += 4;
> + }

This looks wrong. Surely you should be decrementing stats by the values
that were read above, not the 'dummy' value read later.

> + return &dev->stats;
> +}
> +
> +/*
> + * Receive packets
> + */
> +static int emac_rx(struct net_device *dev, struct emac_desc *desc_ack)
> +{
[...]
> + /* Give back old sk_buff */
> + netif_rx(skb_old);
> + dev->last_rx = jiffies;

No need to set last_rx; the networking core does it.

> + /* Fill statistic */
> + dev->stats.rx_packets++;
> + dev->stats.rx_bytes += pkt_len;
> + } else {
> + printk(KERN_WARNING "%s: Memory squeeze, dropping packet.\n", dev->name);

Should be rate-limited or controlled by message-level (see netif_info()
and related macros in netdevice.h).

[...]
> +static int emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + volatile struct emac_desc *desc;
> + volatile struct emac_desc *prev_desc = NULL;
> + ushort pkt_len = skb->len;
> + unsigned long flags;
> +
> + if (ep->tx_full) {
> + printk(KERN_WARNING "%s: tx queue full\n", dev->name);

Definitely don't log this by default.

> + dev->stats.tx_dropped++;

No, the packet is not dropped in this case.

> + return NETDEV_TX_BUSY;
> + }
> +
> + /* Pad short frame */
> + if (unlikely(pkt_len < ETH_ZLEN)) {
> + if (skb_padto(skb, ETH_ZLEN)) {
> + netif_wake_queue(dev);

The queue is already awake!

And in this case you *are* dropping the packet, so you could increment
tx_dropped.

> + return NETDEV_TX_OK;
> + }
> + pkt_len = ETH_ZLEN;
> + }
[...]
> +static void emac_handle_host_interrupt(struct net_device *dev)
> +{
> + struct emac_private *ep = netdev_priv(dev);
> + unsigned long status;
> +
> + /* Handle host error */
> + status = emac_get_reg(EMAC_MACSTATUS);
> +
> + /* Check if the problem occurs on our channel when we are slave */
> + if ((ep->slave)
> + && (((status & EMAC_M_RXERRCH) >> EMAC_S_RXERRCH) != IDX_TO_CHAN(emac_idx))
> + && (((status & EMAC_M_TXERRCH) >> EMAC_S_TXERRCH) != IDX_TO_CHAN(emac_idx)))
> + return;
> +
> + if ((status & EMAC_M_RXERRCODE) == (EMAC_V_OWNERSHIP << EMAC_S_RXERRCODE)) {
> + printk(KERN_ERR "%s: EMAC rx ring full\n", dev->name);

Should be rate-limited or controlled by message-level.

> + dev->stats.rx_fifo_errors++;
> + } else
> + printk(KERN_ERR "%s: EMAC fatal host error 0x%lx\n",
> + dev->name, status);
> +
> + DPRINTK(KERN_ERR "%s: Error head=%p desc=%p dirty=%p skb_tx_dirty=%ld count=%ld\n",
> + dev->name, ep->head_tx, ep->cur_tx,
> + ep->dirty_tx, ep->skb_tx_dirty, ep->count_tx);
> +
> + if (!ep->slave) {
> + /* Reconfigure the device */
> + ep->fatal_error = 1;
> + emac_reconfigure_device(dev);
> + }
> +}
[...]
> +#ifdef EMAC_HAS_ALE_SUPPORT
[...]
> +static void emac_set_rx_mode(struct net_device *dev)
[...]
> + /* Set mcast from a list */
> + for (i = 0; i < dev->mc_count; i++, dmi = dmi->next) {
> + u8 *p_dmi = dmi->dmi_addr;

This is the old multicast list format; the code won't even compile now.

It needs to be updated like the !EMAC_HAS_ALE_SUPPORT version has been.

[...]
> +#ifdef EMAC_TIMER_TICK_MDIO
> +/*
> + * This function should be called for each device in the system on a
> + * periodic basis of 100mS (10 times a second). It is used to check the
> + * status of the EMAC and MDIO device.
> + */
> +static void emac_timer_tick(unsigned long data)

That seems excessive! It might be worth checking whether this takes
significant CPU time, and increasing the period when all links are in a
steady state.

[...]
> +static const struct ethtool_ops gemac_ethtool_ops = {
> +};

We (that is, netdev regulars) should make more of the default ethtool
operations work without dev->ethtool_ops set, so you don't have to do
this!

[...]
> +#ifdef EMAC_ARCH_HAS_MAC_ADDR
> + /* SoC or board hw has MAC address */
> + if (config.enetaddr[0] == 0 && config.enetaddr[1] == 0 &&
> + config.enetaddr[2] == 0 && config.enetaddr[3] == 0 &&
> + config.enetaddr[4] == 0 && config.enetaddr[5] == 0) {
[...]

is_zero_ether_addr(config.enetaddr)

Ben.

--
Ben Hutchings, Senior Software Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.

2011-05-21 17:10:32

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Wednesday 11 May 2011 22:13:47 Mark Salter wrote:
> and the GIT tree holding the attached patches is at:
>
> [email protected]:/git/projects/linux-c6x-upstreaming.git
>
> TIA for any feedback and/or guidance on this port.
>

I've taken a very brief look at the repository. These
are the things that stood out at first, in no particular
order:

- You need to reduce the size of the defconfig files using
'make gendefconfig'

- arch/c6x/drivers/ should not exist, just move the drivers
into the respective driver hierarchy (drivers/gpio, ...)

- Do not register static platform devices, they are deprecated.
For devices that are always there, use platform_device_create_simple.
For devices that depend on the specific SoC, use a flattened
device tree to describe the hierarchy of devices.

- Replace your board files with device tree files written
in DTS language as on powerpc, microblaze, etc. Hardcoding
board stuff in the kernel is not the way to go for new
architectures, as we are migrating the existing ones away
from that.

- The CIO console driver should be coverted to use hvc_console.

- Any header file that only includes the asm-generic version
can now use generic infrastructure to generate the header,
so you can remove these files.

- arch/c6x/lib/misc.c appears to be misplaced. Why would you
define abort(), exit() and alloca()? Leftover from the
proprietary compiler?

- Do you really need a.out.h?

- your asm/atomic.h and asm/bitops.h look like they should use
the generic version.

- struct clk support is currently undergoing a rewrite, you should
use the new version once it shows up. If it doesn't work for
you, complain now so we can fix it before it gets merged.

- I would guess that you don't support ISA dma, so don't try to use
asm/dma.h.

- gemac.h and gmdio.h should probably live in the same directory
as the driver using them, not in asm/.

- You are rather inconsistent using MMIO pointer access. You should
always use proper accessors like readl/writel, and use sparse
to check that all mmio pointers are marked as __iomem.
Check all uses of 'volatile' in the code, most of them are wrong
and should be '__iomem' instead. See
Documentation/volatile-considered-harmful.txt

- Fix your readl/writel implementations to do the correct casts
from __iomem pointers.

- Do not use __raw_readl/__raw_writel.

- Remove your IO_ADDRESS(), __REG, VULP, __SYSREG and __SYSREGA.
Replace them with proper use of ioremap().

- Your inb/outb implementations are completely wrong. If you don't
support PCI, best just replace them with BUG(). Set IO_SPACE_LIMIT
to zero to enforce that no driver uses them.

- Go through your machdep.h and make sure that all pointers are
actually used, e.g. mach_floppy_eject /sounds/ like you wouldn't
need it in 2011.

- You have an asm/pci.h but no host implementation. Why is that?

- Why do you have both pll.h and clk.h? Don't they do the same thing?

- Use the common asm-generic/unistd.h instead of your own! A significant
number of the syscalls you define are not needed at all. This will
also simplify merging into glibc.

- Rewrite your ptrace.c to use regsets and the common infrastructure
from kernel/ptrace.c.

- I recommend to split your device drivers into separate git branches
in your repository, to make it easier to see what is coming up,
and to allow merging branches at a time. Not required, but it will
make your life easier.

That's all from me for now. When we have resolved these issues, the
next step would be to create a multi-patch series (e.g. ~20 patches
for arch/c6x/*) split into one patch per topic, and review them
on the linux-arch and linux-kernel mailing lists.

Arnd

2011-05-21 17:46:04

by Geert Uytterhoeven

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Sat, May 21, 2011 at 19:10, Arnd Bergmann <[email protected]> wrote:
> - Do not register static platform devices, they are deprecated.
>  For devices that are always there, use platform_device_create_simple.

platform_device_register_simple.

Gr{oetje,eeting}s,

                        Geert

--
Geert Uytterhoeven -- There's lots of Linux beyond ia32 -- [email protected]

In personal conversations with technical people, I call myself a hacker. But
when I'm talking to journalists I just say "programmer" or something like that.
                                -- Linus Torvalds

2011-06-16 12:54:49

by Mark Salter

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Sat, 2011-05-21 at 19:10 +0200, Arnd Bergmann wrote:
> - Do not use __raw_readl/__raw_writel.
>
> - Remove your IO_ADDRESS(), __REG, VULP, __SYSREG and __SYSREGA.
> Replace them with proper use of ioremap().

If not __raw_readl/__raw_writel, what is the best way to access memory
mapped device registers on a bus that does the endian conversion in
hardware? I still need the endian conversion for devices on PCI bus.

--Mark

2011-06-16 14:02:42

by Arnd Bergmann

[permalink] [raw]
Subject: Re: [PATCH] arch/c6x: new architecture port for linux

On Thursday 16 June 2011, Mark Salter wrote:
> On Sat, 2011-05-21 at 19:10 +0200, Arnd Bergmann wrote:
> > - Do not use __raw_readl/__raw_writel.
> >
> > - Remove your IO_ADDRESS(), __REG, VULP, __SYSREG and __SYSREGA.
> > Replace them with proper use of ioremap().
>
> If not __raw_readl/__raw_writel, what is the best way to access memory
> mapped device registers on a bus that does the endian conversion in
> hardware? I still need the endian conversion for devices on PCI bus.

The best option is to define a bus specific set of accessors that you
can use in the device drivers for that bus and that have well-defined
semantics regarding ordering and endianess.

Typically what happens is that at some point some hardware developer
decides to reuse a piece of logic with the opposite endianess (e.g.
when the same logic is connected to multiple CPUs), so better define
the endianess of the bus independent of the CPU and have a separate
Kconfig option for that.

Arnd